mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
Merge branch 'vapor/production' into vapor/staging
This commit is contained in:
+1
-1
@@ -45,7 +45,7 @@ PUSHER_APP_CLUSTER=mt1
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
FILESYSTEM_DRIVER="documents"
|
||||
FILESYSTEM_DISK="documents"
|
||||
|
||||
JWT_SECRET=
|
||||
JWT_TTL=1440
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=testing
|
||||
|
||||
APP_KEY=base64:utnZQgraE9iHT+4xCoDP2p7MdQmBweGyP0b6Mp1ksds=
|
||||
JWT_SECRET=4DlpggxJJeV1nVeHPPf83mSGsoJEmA8bpuSFdFN0VCvwqkE084iYOqoed0q47Ee2
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=172.18.0.2
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=ci_test_exchange
|
||||
DB_USERNAME=ci
|
||||
DB_PASSWORD=bi9y@T8r
|
||||
+3
-1
@@ -6,6 +6,7 @@
|
||||
**/.idea/
|
||||
.env
|
||||
.env.backup
|
||||
.env.testing.example
|
||||
.phpunit.result.cache
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
@@ -21,7 +22,6 @@ gox.iml
|
||||
rebuild_docker.sh
|
||||
docker/*
|
||||
db/*
|
||||
package-lock.json
|
||||
public/*
|
||||
/public/*
|
||||
/storage/app/public
|
||||
@@ -31,3 +31,5 @@ public
|
||||
.env.production
|
||||
.env.staging
|
||||
.env.development
|
||||
docz/*
|
||||
.phpunit.cache/
|
||||
|
||||
@@ -19,12 +19,19 @@
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
setInterval(function() {
|
||||
window.location.href = "/";
|
||||
}, 60000); // 60000 ms = 1 minute, 300000 ms = 5 minutes
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1>We'll be back soon!</h1>
|
||||
<p>Sorry for the inconvenience but we're performing some maintenance at the moment. We'll be back online shortly!</p>
|
||||
<p>— CIEF EXCHANGE</p>
|
||||
|
||||
<a href="/" class="btn">Go Back Home</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Vendored
+43
-3
@@ -9,8 +9,8 @@
|
||||
pipeline {
|
||||
agent {
|
||||
docker {
|
||||
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'
|
||||
args '--network ci-net --group-add 992 -v /var/run/docker.sock:/var/run/docker.sock'
|
||||
image '303644228504.dkr.ecr.ap-southeast-1.amazonaws.com/jenkins-pipeline-agent-php-8.3:latest'
|
||||
registryCredentialsId "ecr:ap-southeast-1:aws-ec2-instance-iam-role"
|
||||
registryUrl "https://303644228504.dkr.ecr.ap-southeast-1.amazonaws.com"
|
||||
}
|
||||
@@ -53,6 +53,15 @@ pipeline {
|
||||
branch: GIT_BRANCH
|
||||
)
|
||||
break
|
||||
case "vapor/test": //cief todo: 137
|
||||
pusherKeyCredId = 'pusher-test-key'
|
||||
pusherCluster = 'ap1'
|
||||
git(
|
||||
url: 'https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git',
|
||||
credentialsId: 'gitlab-jenkins-localhost',
|
||||
branch: GIT_BRANCH
|
||||
)
|
||||
break
|
||||
case "origin/dillon/34-jenkins-vapor":
|
||||
git(
|
||||
url: 'https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git',
|
||||
@@ -84,7 +93,35 @@ pipeline {
|
||||
|
||||
stage('Tests') {
|
||||
steps {
|
||||
sh 'vendor/bin/phpunit tests/Unit'
|
||||
// sh 'vendor/bin/phpunit tests/Unit'
|
||||
sh '''
|
||||
set -e
|
||||
|
||||
export APP_ENV=testing
|
||||
# export APP_KEY=$(php -r "echo 'base64:'.base64_encode(random_bytes(32));")
|
||||
# export JWT_SECRET=$(php -r "echo bin2hex(random_bytes(32));")
|
||||
|
||||
# Show which PHP binary is used
|
||||
which php
|
||||
php -v
|
||||
|
||||
# List PHP modules to confirm pdo_mysql
|
||||
php -m | grep pdo_mysql || echo "pdo_mysql not loaded"
|
||||
|
||||
# Show DB environment variables
|
||||
echo "DB_CONNECTION=$DB_CONNECTION"
|
||||
echo "DB_HOST=$DB_HOST"
|
||||
echo "DB_PORT=$DB_PORT"
|
||||
echo "DB_DATABASE=$DB_DATABASE"
|
||||
echo "DB_USERNAME=$DB_USERNAME"
|
||||
# Do NOT echo password in logs
|
||||
|
||||
php artisan migrate:fresh --force
|
||||
|
||||
vendor/bin/phpunit -c phpunit.ci.xml --group ok_to_run
|
||||
# vendor/bin/phpunit --filter AuthenticationTest
|
||||
# vendor/bin/phpunit -c phpunit.ci.xml --filter ListOrderTrackingLogicTest
|
||||
'''
|
||||
script{
|
||||
currentBuild.description = 'Step 4 of 6 Completed'
|
||||
}
|
||||
@@ -107,6 +144,9 @@ pipeline {
|
||||
case "vapor/development":
|
||||
sh "vendor/bin/vapor deploy development --message='${gitCommitMessage}'"
|
||||
break
|
||||
case "vapor/test":
|
||||
sh "vendor/bin/vapor deploy test --message='${gitCommitMessage}'"
|
||||
break
|
||||
case "origin/dillon/34-jenkins-vapor":
|
||||
sh "vendor/bin/vapor deploy development --message='${gitCommitMessage}'"
|
||||
break
|
||||
|
||||
@@ -4,7 +4,6 @@ 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
|
||||
{
|
||||
@@ -19,6 +18,6 @@ class IsNotFullyRefunded implements Filter
|
||||
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'));
|
||||
->havingRaw('total_refund_amount < original_amount');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class IsPartialRefund implements Filter
|
||||
{
|
||||
@@ -17,9 +16,9 @@ class IsPartialRefund implements Filter
|
||||
{
|
||||
return $builder->whereHas('owner', function ($q) use ($value) {
|
||||
if ($value) {
|
||||
$q->where('original_amount', '!=', DB::raw('transactions.original_amount'));
|
||||
$q->whereRaw('original_amount != transactions.original_amount');
|
||||
} else {
|
||||
$q->where('original_amount', DB::raw('transactions.original_amount'));
|
||||
$q->whereRaw('original_amount = transactions.original_amount');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ class LogHelper
|
||||
{
|
||||
$envVar = env('LARAVEL_VAPOR_ENABLED');
|
||||
$isLocal = env('VAPOR_ENV') === 'local';
|
||||
Log::info("Info: " . json_encode($message));
|
||||
Log::info("Info: {$message}, channelName: {$this->channelName}, envVar {$envVar}");
|
||||
if ($envVar && !$isLocal) {
|
||||
Log::channel($this->channelName.'_vapor')->info($message);
|
||||
|
||||
@@ -46,7 +46,7 @@ class SendWelcomeVoucherEmail implements ShouldQueue
|
||||
{
|
||||
$currentDatetime = Carbon::now();
|
||||
$dateToCompare = Carbon::parse($this->voucher->end_date);
|
||||
if (!$this->user->hasAttribute($this->voucher->code."_EMAIL_COUNT")
|
||||
if (!$this->user->hasCustomAttribute($this->voucher->code."_EMAIL_COUNT")
|
||||
&& $this->user->rewards->where('voucher_id', $this->voucher->id)->count() > 0
|
||||
&& $currentDatetime->isBefore($dateToCompare))
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Accounts\Standards\Validators;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractValidation;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\UserObject;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UserCreateValidation extends AbstractValidation
|
||||
{
|
||||
@@ -28,9 +29,9 @@ class UserCreateValidation extends AbstractValidation
|
||||
protected function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required',
|
||||
'email' => 'required|unique:users',
|
||||
'password' => 'required',
|
||||
'name' => 'required',
|
||||
'email' => ['required', Rule::unique('users')],
|
||||
'password' => 'required',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Accounts\Standards\Validators;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractValidation;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\RegistrationObject;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UserRegistrationValidation extends AbstractValidation
|
||||
{
|
||||
@@ -32,7 +33,7 @@ class UserRegistrationValidation extends AbstractValidation
|
||||
{
|
||||
return [
|
||||
'name' => 'required',
|
||||
'email' => 'required|email|max:255|unique:users,email',
|
||||
'email' => ['required', 'email', 'max:255', Rule::unique('users', 'email')],
|
||||
'password' => 'required|min:6|confirmed',
|
||||
'type' => 'required',
|
||||
'status' => 'required'
|
||||
|
||||
@@ -86,6 +86,12 @@ class CallbackBillplzLogic
|
||||
$billplzXSignatureObject = new BillplzXSignatureObject($request);
|
||||
|
||||
if(!$billplzXSignatureObject->isValidSignature()){
|
||||
Log::info('Billplz signature validation failed', [
|
||||
'computed_signature' => $billplzXSignatureObject->getBillPlzComputedXSignature(),
|
||||
'request_signature' => $request->input('x_signature'),
|
||||
'constructed_string' => $billplzXSignatureObject->getBillPlzConstructString(),
|
||||
'request_data' => $request->all(),
|
||||
]); //cief todo: 137 - DEBUG
|
||||
throw new MalformedRequestException('Billplz Payment validation failed.');
|
||||
}
|
||||
|
||||
|
||||
@@ -67,11 +67,13 @@ class ApprovePurchaseOrderLogic extends AbstractControllerLogic
|
||||
|
||||
$this->updatesTransactionStatus->execute($purchaseOrder, ApprovalStatus::APPROVED);
|
||||
|
||||
$bookingOriginalStatus = $booking->status;
|
||||
|
||||
$this->createInvoiceTransactionProcessor->execute($booking, "", null, [
|
||||
'generateEInvoice' => false,
|
||||
'generateEInvoiceWithNormalInvoiceTemplate' => false,
|
||||
'generateEInvoiceRefund' => false,
|
||||
'bookingOriginalStatus' => $booking->status
|
||||
'bookingOriginalStatus' => $bookingOriginalStatus
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
+15
@@ -3,6 +3,7 @@
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\CreatePaymentVerificationDocumentDTO;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
@@ -21,6 +22,7 @@ use App\Models\Company;
|
||||
use App\Models\Document;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CreatePaymentVerificationDocumentLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -93,6 +95,19 @@ class CreatePaymentVerificationDocumentLogic extends AbstractControllerLogic
|
||||
|
||||
$object = new DocumentObject(DocumentType::CUSTOMER_PAYMENT_PROOF, $request->input('files'), '', ApprovalStatus::PENDING_VERIFICATION, 'payments');
|
||||
|
||||
$hasExcel = false;
|
||||
foreach ($object->getFiles() as $file) {
|
||||
$decodedFile = json_decode($file);
|
||||
if (($decodedFile->extension) === 'excel') {
|
||||
$hasExcel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasExcel) {
|
||||
throw new MalformedRequestException("Please upload files in PDF, JPEG, or PNG format.");
|
||||
}
|
||||
|
||||
/** @var Document $document */
|
||||
$document = $this->createsDocument->execute($transaction, $object);
|
||||
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ class CreatePurchaseOrderFor1688OrderProcessor
|
||||
'generateEInvoice' => false,
|
||||
'generateEInvoiceWithNormalInvoiceTemplate' => false,
|
||||
'generateEInvoiceRefund' => false,
|
||||
'bookingOriginalStatus' => ApprovalStatus::COMPLETED
|
||||
'bookingOriginalStatus' => ApprovalStatus::COMPLETED //cief todo: 151
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,15 +52,24 @@ class RegenerateInvoiceBookingV2Processor
|
||||
|
||||
public function execute(Booking $booking,
|
||||
bool $eInvoiceWithNormalInvoiceTemplate = false,
|
||||
bool $eInvoiceWithRefund = false, bool $eInvoiceTry = false)
|
||||
bool $eInvoiceWithRefund = false,
|
||||
bool $eInvoiceTry = false ////cief todo: 151 - getting ready to get rid of eInvoiceTry as a parameter
|
||||
)
|
||||
{
|
||||
$bookingOriginalStatus = $booking->status;
|
||||
|
||||
if($eInvoiceTry){
|
||||
if($booking->invoice_status === ApprovalStatus::APPROVED){
|
||||
$bookingOriginalStatus = ApprovalStatus::COMPLETED;
|
||||
}
|
||||
}
|
||||
// Log::info('E-invoice flags', [
|
||||
// 'eInvoiceWithNormalInvoiceTemplate' => $eInvoiceWithNormalInvoiceTemplate,
|
||||
// 'eInvoiceWithRefund' => $eInvoiceWithRefund,
|
||||
// 'eInvoiceTry' => $eInvoiceTry,
|
||||
// ]);
|
||||
|
||||
// if($eInvoiceTry){
|
||||
// if($booking->invoice_status === ApprovalStatus::APPROVED){
|
||||
// // cief todo: must make sure TransactionType::BILL has status Approved (2)
|
||||
// $bookingOriginalStatus = ApprovalStatus::COMPLETED;
|
||||
// }
|
||||
// }
|
||||
|
||||
if(!$eInvoiceWithRefund){
|
||||
$this->updatesBookingStatus->execute($booking, ApprovalStatus::APPROVED);
|
||||
@@ -116,9 +125,11 @@ class RegenerateInvoiceBookingV2Processor
|
||||
$this->deletesTransaction->execute($row);
|
||||
}
|
||||
|
||||
$kvpCopies = $latestInvoice->attributesKVP->map(function ($kvp) {
|
||||
return $kvp->replicate();
|
||||
});
|
||||
if($latestInvoice){
|
||||
$kvpCopies = $latestInvoice->attributesKVP->map(function ($kvp) {
|
||||
return $kvp->replicate();
|
||||
});
|
||||
}
|
||||
}
|
||||
//for E-INVOICE
|
||||
else {
|
||||
|
||||
@@ -17,7 +17,7 @@ class UpdatesBookingInvoiceStatus extends AbstractUpdateRecord
|
||||
*/
|
||||
public function execute(Booking $model, UpdateBookingInvoiceStatusObject $object)
|
||||
{
|
||||
$model->invoice_status = $object->getInvoiceStatus();
|
||||
$model->invoice_status = $object->getInvoiceStatus(); //invoice_status first used on Export Sales Invoice Report
|
||||
return $this->handler($model);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class UpdateCompanyLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$object = new CompanyObject($request->input('name'), $request->input('reference'), $request->input('type'));
|
||||
$object = new CompanyObject($request->input('name'), $request->input('reference'), $request->input('business_type'), $request->input('type'));
|
||||
|
||||
$this->canUpdateCompany->passes($object);
|
||||
|
||||
@@ -67,4 +67,4 @@ class UpdateCompanyLogic extends AbstractControllerLogic
|
||||
return $this->resourceResponse(new CompanyResource($query));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Classes\General\Interfaces\DataTransferObject;
|
||||
use App\Classes\ValueObjects\Constants\FileType;
|
||||
use Illuminate\Support\Str;
|
||||
use Intervention\Image\ImageManager;
|
||||
use Intervention\Image\Drivers\Gd\Driver;
|
||||
|
||||
class FileObject implements DataTransferObject
|
||||
{
|
||||
@@ -28,7 +29,13 @@ class FileObject implements DataTransferObject
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return in_array($this->getExtension(), ['pdf', 'excel', 'text']) ? $this->data : (new imageManager())->make($this->data);
|
||||
// intervention/image v2: old
|
||||
//return in_array($this->getExtension(), ['pdf', 'excel', 'text']) ? $this->data : (new imageManager())->make($this->data);
|
||||
|
||||
// intervention/image v3: new
|
||||
return in_array($this->getExtension(), ['pdf', 'excel', 'text'])
|
||||
? $this->data
|
||||
: (new ImageManager(new Driver()))->read($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +60,7 @@ class FileObject implements DataTransferObject
|
||||
*/
|
||||
public function getExtension(): string
|
||||
{
|
||||
if(array_key_exists($this->getMimeType(), FileType::EXTENSION)){
|
||||
if (array_key_exists($this->getMimeType(), FileType::EXTENSION)) {
|
||||
return FileType::EXTENSION[$this->getMimeType()];
|
||||
}
|
||||
|
||||
@@ -66,9 +73,10 @@ class FileObject implements DataTransferObject
|
||||
*/
|
||||
public function getDecodedData(): string
|
||||
{
|
||||
// intervention/image v3: Use encode()->toDataUri() instead of encode('data-url')->encoded
|
||||
return in_array($this->getExtension(), ['pdf', 'excel', 'text']) ?
|
||||
base64_decode((explode('base64,', $this->getData()))[1]):
|
||||
$this->getData()->encode('data-url')->encoded;
|
||||
base64_decode((explode('base64,', $this->getData()))[1]) :
|
||||
$this->getData()->encode()->toDataUri();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,7 +32,8 @@ class ConvertsBase64ToFile
|
||||
* @return array
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function convert($files = []){
|
||||
public function convert($files = [])
|
||||
{
|
||||
foreach ($files as $file) {
|
||||
|
||||
$object = new FileObject($file);
|
||||
@@ -48,41 +49,47 @@ class ConvertsBase64ToFile
|
||||
* @param FileObject $file
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
private function generatePDF(FileObject $file){
|
||||
private function generatePDF(FileObject $file)
|
||||
{
|
||||
|
||||
$filePath = $this->generateFile($file);
|
||||
$this->updateFiles($file, [ 'original' => [ 'file' => $filePath ] ]);
|
||||
$this->updateFiles($file, ['original' => ['file' => $filePath]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FileObject $file
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
private function generateImage(FileObject $file){
|
||||
private function generateImage(FileObject $file)
|
||||
{
|
||||
|
||||
$fileInfo = [];
|
||||
|
||||
foreach (['original' => null, 'large' => 800, 'medium' => 480, 'small' => 320] as $size => $value) {
|
||||
$suffix = $size !== 'original' ? '_'.$size : '';
|
||||
$suffix = $size !== 'original' ? '_' . $size : '';
|
||||
|
||||
if($size !== 'original') {
|
||||
$thumbnail = $file->getData()->widen($value, function ($constraint) {
|
||||
if ($size !== 'original') {
|
||||
// intervention/image v2: old
|
||||
// $thumbnail = $file->getData()->widen($value, function ($constraint) {
|
||||
// $constraint->upsize();
|
||||
// })->heighten($value, function ($constraint) {
|
||||
// $constraint->upsize();
|
||||
// });
|
||||
// $file->setData($thumbnail->encode('data-url')->encoded);
|
||||
|
||||
$constraint->upsize();
|
||||
|
||||
})->heighten($value, function ($constraint) {
|
||||
// intervention/image v3: Use scaleDown() instead of widen()/heighten()
|
||||
// scaleDown() maintains aspect ratio and prevents upsizing by default
|
||||
$thumbnail = $file->getData()->scaleDown(width: $value, height: $value);
|
||||
|
||||
$constraint->upsize();
|
||||
|
||||
});
|
||||
|
||||
$file->setData($thumbnail->encode('data-url')->encoded);
|
||||
// intervention/image v3: Use encode()->toDataUri() instead of encode('data-url')->encoded
|
||||
$file->setData($thumbnail->encode()->toDataUri());
|
||||
}
|
||||
|
||||
|
||||
$filePath = $this->generateFile($file, $suffix);
|
||||
|
||||
$fileInfo[] = [ $size => [ 'file' => $filePath, 'width' => $file->getData()->width(), 'height' => $file->getData()->height() ]];
|
||||
$fileInfo[] = [$size => ['file' => $filePath, 'width' => $file->getData()->width(), 'height' => $file->getData()->height()]];
|
||||
|
||||
|
||||
}
|
||||
@@ -97,16 +104,16 @@ class ConvertsBase64ToFile
|
||||
* @return string
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
private function generateFile(FileObject $file, string $suffix = '') {
|
||||
private function generateFile(FileObject $file, string $suffix = '')
|
||||
{
|
||||
|
||||
$filesystemDriver = Storage::getDefaultDriver();
|
||||
if($filesystemDriver === 's3'){
|
||||
$filePath = 'documents/'.$this->path.'/'.$file->getFileName().$suffix.'.'.$file->getExtension();
|
||||
if ($filesystemDriver === 's3') {
|
||||
$filePath = 'documents/' . $this->path . '/' . $file->getFileName() . $suffix . '.' . $file->getExtension();
|
||||
Storage::put($filePath, $file->getDecodedData(), 's3');
|
||||
return $filePath;
|
||||
}
|
||||
else{
|
||||
$filePath = $this->path.'/'.$file->getFileName().$suffix.'.'.$file->getExtension();
|
||||
} else {
|
||||
$filePath = $this->path . '/' . $file->getFileName() . $suffix . '.' . $file->getExtension();
|
||||
Storage::disk('documents')->put($filePath, $file->getDecodedData());
|
||||
return $filePath;
|
||||
}
|
||||
@@ -117,10 +124,11 @@ class ConvertsBase64ToFile
|
||||
* @param array $fileInfo
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
private function updateFiles(FileObject $file, array $fileInfo){
|
||||
private function updateFiles(FileObject $file, array $fileInfo)
|
||||
{
|
||||
$this->filesInfo[] = json_encode([
|
||||
'path' => $this->path,
|
||||
'filename' => $file->getFileName().'.'.$file->getExtension(),
|
||||
'filename' => $file->getFileName() . '.' . $file->getExtension(),
|
||||
'mime_type' => $file->getMimeType(),
|
||||
'extension' => $file->getExtension(),
|
||||
'file_info' => $fileInfo
|
||||
|
||||
@@ -19,14 +19,19 @@ class CreatesFiles extends AbstractUpdateRelationshipRecord
|
||||
{
|
||||
$models = [];
|
||||
|
||||
// foreach ($object->getFiles() as $file) {
|
||||
// $model = new File(['file' => $file]);
|
||||
// $models[] = $this->handler($document->files(), $model);
|
||||
// }
|
||||
|
||||
foreach ($object->getFiles() as $file) {
|
||||
|
||||
$model = new File(['file' => $file]);
|
||||
$fileData = is_string($file) ? json_decode($file, true) : $file;
|
||||
$model = new File(['file' => $fileData]);
|
||||
$models[] = $this->handler($document->files(), $model);
|
||||
|
||||
}
|
||||
|
||||
return $models;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class CreatesConstant extends AbstractUpdateRelationshipRecord
|
||||
$model = new SegmentConstant();
|
||||
$model->name = $object->getName();
|
||||
$model->reference = $object->getReference();
|
||||
$model->detail = json_encode($object->getDetail());
|
||||
$model->detail = $object->getDetail();
|
||||
|
||||
return $this->handler($segment->constants(), $model);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class UpdatesConstant extends AbstractUpdateRecord
|
||||
{
|
||||
$model->name = $object->getName();
|
||||
$model->reference = $object->getReference();
|
||||
$model->detail = json_encode($object->getDetail());
|
||||
$model->detail = $object->getDetail();
|
||||
|
||||
return $this->handler($model);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SegmentObject;
|
||||
use App\Classes\Modules\Segments\Standards\Validators\SegmentValidation;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CanCreateSegment extends AbstractRule
|
||||
{
|
||||
@@ -28,7 +29,10 @@ class CanCreateSegment extends AbstractRule
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
if (!Auth::user()->can('add segment')) {
|
||||
/** @var \App\Models\User $user */
|
||||
$user = Auth::user();
|
||||
|
||||
if (!$user->can('add segment')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -53,4 +57,4 @@ class CanCreateSegment extends AbstractRule
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ class CreatePaymentProofDocumentLogic extends AbstractControllerLogic
|
||||
'generateEInvoice' => false,
|
||||
'generateEInvoiceWithNormalInvoiceTemplate' => false,
|
||||
'generateEInvoiceRefund' => false,
|
||||
'bookingOriginalStatus' => ApprovalStatus::COMPLETED
|
||||
'bookingOriginalStatus' => ApprovalStatus::COMPLETED //cief todo: 151
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ class GenerateCreditNotePdfV2Logic
|
||||
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
|
||||
$autoCountInvoiceId = '';
|
||||
$autoCountEInvoiceValidationLink = 'CIEF';
|
||||
$kvpCreditNoteNormalOptInOverride = $transaction->attributesKVP()->where('key', KVPKey::CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE)->latest()->first(); //transaction type 6
|
||||
|
||||
if($transaction->type === TransactionType::REFUND){
|
||||
//Retrieve TransactionType::CREDIT_NOTE
|
||||
@@ -69,6 +70,7 @@ class GenerateCreditNotePdfV2Logic
|
||||
if($kvp){
|
||||
$kvpOwner = $kvp->owner;
|
||||
if($kvpOwner && $kvpOwner instanceof Transaction && $kvpOwner->type === TransactionType::REFUND){
|
||||
$kvpCreditNoteNormalOptInOverride = $kvpOwner->attributesKVP()->where('key', KVPKey::CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE)->latest()->first(); //transaction type 6
|
||||
$booking = $kvpOwner->owner->booking;
|
||||
}
|
||||
}
|
||||
@@ -144,6 +146,10 @@ class GenerateCreditNotePdfV2Logic
|
||||
Log::info('Based on booking created date, E-Credit Note started and company do not wants e-invoice');
|
||||
$pdfTemplateName = 'pages.pdfs.credit_note_v2';
|
||||
}
|
||||
|
||||
if($kvpCreditNoteNormalOptInOverride && $kvpCreditNoteNormalOptInOverride->value == 1){
|
||||
$pdfTemplateName = 'pages.pdfs.credit_note_v2';
|
||||
}
|
||||
}
|
||||
else{
|
||||
Log::info('Based on booking created date, E-Credit Note not yet started. / Not Yet Ready.');
|
||||
|
||||
+1
-1
@@ -187,7 +187,7 @@ class ImportPurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
$sheet = $collection->first()->skip(1);
|
||||
|
||||
$products = $sheet->map(function ($row) {
|
||||
Log::info($row);
|
||||
Log::info('ImportPurchaseOrderTransactionLogic Row data: ' . json_encode($row));
|
||||
$stockCode = $row[0];
|
||||
$description = $row[1];
|
||||
$quantity = $row[2];
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Transactions\Standards\Rules\CanUpdateCreditNote;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UpdateCreditNoteOptLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification(): array
|
||||
{
|
||||
return [
|
||||
'title' => 'Updated Credit Note',
|
||||
'message' => 'You have successfully updated this credit note'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanUpdateCreditNote */
|
||||
private $canUpdateCreditNote;
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/** @var CreatesKeyValuePair */
|
||||
private $createsKeyValuePair;
|
||||
|
||||
/** @var UpdatesKeyValuePair */
|
||||
private $updatesKeyValuePair;
|
||||
|
||||
/**
|
||||
* UpdateCreditNoteOptLogic constructor.
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
* @param CreatesKeyValuePair $createsKeyValuePair
|
||||
* @param UpdatesKeyValuePair $updatesKeyValuePair
|
||||
* @param CanUpdateCreditNote $canUpdateCreditNote
|
||||
*/
|
||||
public function __construct(FetchesTransaction $fetchesTransaction, FetchesCompany $fetchesCompany, CreatesKeyValuePair $createsKeyValuePair, UpdatesKeyValuePair $updatesKeyValuePair, CanUpdateCreditNote $canUpdateCreditNote)
|
||||
{
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
$this->createsKeyValuePair = $createsKeyValuePair;
|
||||
$this->updatesKeyValuePair = $updatesKeyValuePair;
|
||||
$this->canUpdateCreditNote = $canUpdateCreditNote;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return string|\Symfony\Component\HttpFoundation\Response
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request): JsonResponse
|
||||
{
|
||||
$this->canUpdateCreditNote->passes();
|
||||
|
||||
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
|
||||
|
||||
$kvp = $transaction->attributesKVP()->where('key', KVPKey::CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE)->latest()->first();
|
||||
|
||||
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
|
||||
if($supplier->e_invoice === 1) {
|
||||
if($kvp && $kvp->value == 1) {
|
||||
$this->updateOrCreateKeyValuePair($transaction, KVPKey::CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->updateOrCreateKeyValuePair($transaction, KVPKey::CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE, 1);
|
||||
}
|
||||
}
|
||||
return $this->response([]);
|
||||
}
|
||||
|
||||
private function updateOrCreateKeyValuePair($transaction, $key, $value)
|
||||
{
|
||||
$keyValuePairObject = new KeyValuePairObject($key, $value);
|
||||
$metadata = $transaction->attributesKVP()->where('key', $key)->first();
|
||||
|
||||
if ($metadata) {
|
||||
$this->updatesKeyValuePair->execute($metadata, $keyValuePairObject);
|
||||
} else {
|
||||
$this->createsKeyValuePair->execute($transaction, $keyValuePairObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,10 @@ class CreateInvoiceDocumentProcessor
|
||||
}
|
||||
else{
|
||||
$lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->latest()->first();
|
||||
|
||||
if(!$lastPaymentTransaction){
|
||||
$lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::REFUNDED])->latest()->first();
|
||||
}
|
||||
}
|
||||
|
||||
$documentDate = $lastPaymentTransaction->created_at;
|
||||
@@ -115,6 +119,9 @@ class CreateInvoiceDocumentProcessor
|
||||
}
|
||||
else{
|
||||
$payment = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->first();
|
||||
if(!$payment){
|
||||
$payment = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::REFUNDED])->first();
|
||||
}
|
||||
}
|
||||
|
||||
$refundAmount = $payment->transactions()->refunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->sum('amount');
|
||||
|
||||
+223
-187
@@ -14,7 +14,9 @@ use App\Classes\Modules\Bookings\Services\CalculatesBookingPaidAmount;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingCurrencyAverageRate;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus;
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingInvoiceStatus;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\UpdateBookingInvoiceStatusObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\SegmentConstants;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
@@ -53,6 +55,9 @@ class CreateInvoiceTransactionV2Processor
|
||||
/** @var UpdatesBookingStatus */
|
||||
private $updatesBookingStatus;
|
||||
|
||||
/** @var UpdatesBookingInvoiceStatus */
|
||||
private $updatesBookingInvoiceStatus;
|
||||
|
||||
/** @var CreateInvoiceDocumentProcessor */
|
||||
private $invoiceDocumentProcessor;
|
||||
|
||||
@@ -74,8 +79,9 @@ class CreateInvoiceTransactionV2Processor
|
||||
* @param UpdatesBookingStatus $updatesBookingStatus
|
||||
* @param CreateInvoiceDocumentProcessor $invoiceDocumentProcessor
|
||||
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
|
||||
* @param UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus
|
||||
*/
|
||||
public function __construct(ListsTransactions $listsTransactions, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPaidAmount $calculatesBookingPaidAmount, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount, FetchesServiceConfigurations $fetchesServiceConfigurations, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, UpdatesBookingStatus $updatesBookingStatus, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
|
||||
public function __construct(ListsTransactions $listsTransactions, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPaidAmount $calculatesBookingPaidAmount, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount, FetchesServiceConfigurations $fetchesServiceConfigurations, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, UpdatesBookingStatus $updatesBookingStatus, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus)
|
||||
{
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
@@ -87,6 +93,7 @@ class CreateInvoiceTransactionV2Processor
|
||||
$this->updatesBookingStatus = $updatesBookingStatus;
|
||||
$this->invoiceDocumentProcessor = $invoiceDocumentProcessor;
|
||||
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
|
||||
$this->updatesBookingInvoiceStatus = $updatesBookingInvoiceStatus;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,11 +113,15 @@ class CreateInvoiceTransactionV2Processor
|
||||
$generateEInvoiceRefund = $options['generateEInvoiceRefund'] ?? false;
|
||||
$bookingOriginalStatus = $options['bookingOriginalStatus'] ?? null;
|
||||
|
||||
$bookingOriginalStatus = null; //cief todo: 151 - getting ready to get rid of bookingOriginalStatus as an options parameter
|
||||
|
||||
// Log::info('CreateInvoiceTransactionV2Processor generateEInvoice:' . json_encode($generateEInvoice));
|
||||
// Log::info('CreateInvoiceTransactionV2Processor generateEInvoiceWithNormalInvoiceTemplate: ' . json_encode($generateEInvoiceWithNormalInvoiceTemplate));
|
||||
// Log::info('CreateInvoiceTransactionV2Processor generateEInvoiceRefund: ' . json_encode($generateEInvoiceRefund));
|
||||
// Log::info('CreateInvoiceTransactionV2Processor bookingOriginalStatus: ' . json_encode($bookingOriginalStatus));
|
||||
|
||||
$proceed = true;
|
||||
|
||||
if ($booking->status === ApprovalStatus::COMPLETED && !$generateEInvoiceRefund) {
|
||||
Log::info('CreateInvoiceTransactionV2Processor Check 1 Bypass New Business Logic Update for booking ' . $booking->id);
|
||||
// return;
|
||||
@@ -121,11 +132,14 @@ class CreateInvoiceTransactionV2Processor
|
||||
$booking_amount = $booking->fix_amount;
|
||||
|
||||
if ((float) $booking_amount === (float) $refund_amount && !$generateEInvoiceRefund) {
|
||||
return;
|
||||
Log::info('CreateInvoiceTransactionV2Processor Check 3 Bypass New Business Logic Update for booking ' . $booking->id);
|
||||
//return;
|
||||
}
|
||||
|
||||
// confirm that booking amount has been fully paid
|
||||
if ((float) $booking_amount > (float) $payable_amount) {
|
||||
Log::info('CreateInvoiceTransactionV2Processor return 1');
|
||||
$proceed = false;
|
||||
return;
|
||||
}
|
||||
// confirm that all payments has been transferred
|
||||
@@ -134,219 +148,241 @@ class CreateInvoiceTransactionV2Processor
|
||||
// return;
|
||||
}
|
||||
|
||||
$purchaseOrder = $booking->transactions()
|
||||
$completedPurchaseOrder = $booking->transactions()
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
->complete()
|
||||
->first();
|
||||
$purchaseOrder = $completedPurchaseOrder;
|
||||
|
||||
if(!$purchaseOrder){
|
||||
//was use for $generateEInvoiceRefund true
|
||||
$purchaseOrder = $booking->transactions()
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
->where('status', ApprovalStatus::PENDING_SUBMISSION)
|
||||
->first();
|
||||
}
|
||||
|
||||
$constants = SegmentConstant::where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->id', $booking->service->id)->first();
|
||||
// if ($constants->detail->is_billable && !$purchaseOrder && !$generateEInvoiceRefund) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
$transaction = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->latest()->get()[0];
|
||||
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
|
||||
|
||||
// Check if eInvoice implementation has started and company opted in for eInvoice
|
||||
$eInvoice = false;
|
||||
$eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
|
||||
$bookingCreatedDate = Carbon::parse($booking->created_at);
|
||||
$eInvoiceRequestedDate = Carbon::parse($supplier->e_invoice_requested_at);
|
||||
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && ($bookingCreatedDate->isAfter($eInvoiceRequestedDate) || $bookingCreatedDate->diffInMinutes($eInvoiceRequestedDate) <= 60) && $supplier->e_invoice === 1) {
|
||||
$eInvoice = true;
|
||||
}
|
||||
$kvp = $booking->attributesKVP()->where('key', KVPKey::BOOKING_EINVOICE_ELIGIBLE)->first();
|
||||
if($kvp){
|
||||
$eInvoice = true;
|
||||
}
|
||||
|
||||
if($generateEInvoiceWithNormalInvoiceTemplate){
|
||||
$invoiceNo = ""; //July 2025 workaround generate normal invoice instead of E-Invoice
|
||||
}
|
||||
|
||||
if($invoiceNo){
|
||||
$billNumber = $invoiceNo;
|
||||
if($this->calculatesBookingTransferredAmount->execute($booking) === $this->calculatesBookingPaidAmount->execute($booking) && $completedPurchaseOrder) {
|
||||
$bookingOriginalStatus = ApprovalStatus::COMPLETED;
|
||||
}
|
||||
else{
|
||||
$billNUmberPrefix = $eInvoice ? 'EINV-' : 'INV-';
|
||||
if($generateEInvoiceWithNormalInvoiceTemplate){
|
||||
$billNUmberPrefix = 'INV-'; //July 2025 workaround generate normal invoice instead of E-Invoice
|
||||
$bookingOriginalStatus = ApprovalStatus::APPROVED;
|
||||
}
|
||||
|
||||
if($proceed){
|
||||
if(!$purchaseOrder && $generateEInvoiceRefund){
|
||||
$purchaseOrder = $booking->transactions()
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
->where('status', ApprovalStatus::PENDING_SUBMISSION)
|
||||
->first();
|
||||
}
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute($billNUmberPrefix);
|
||||
}
|
||||
|
||||
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::PAYMENT, $generateEInvoiceRefund);
|
||||
$constants = SegmentConstant::where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->id', $booking->service->id)->first();
|
||||
// if ($constants->detail->is_billable && !$purchaseOrder && !$generateEInvoiceRefund) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if($generateEInvoiceRefund){
|
||||
$total_service_charge = $booking->transactions()
|
||||
$transaction = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereIn('status', [ApprovalStatus::REFUNDED])
|
||||
->sum('service_charge');
|
||||
->latest()->get()[0];
|
||||
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
|
||||
|
||||
$total_tax = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereIn('status', [ApprovalStatus::REFUNDED])
|
||||
->sum('tax');
|
||||
}
|
||||
else{
|
||||
$total_service_charge = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
|
||||
->sum('service_charge');
|
||||
// Check if eInvoice implementation has started and company opted in for eInvoice
|
||||
$eInvoice = false;
|
||||
$eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
|
||||
$bookingCreatedDate = Carbon::parse($booking->created_at);
|
||||
$eInvoiceRequestedDate = Carbon::parse($supplier->e_invoice_requested_at);
|
||||
|
||||
$total_tax = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
|
||||
->sum('tax');
|
||||
}
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && ($bookingCreatedDate->isAfter($eInvoiceRequestedDate) || $bookingCreatedDate->diffInMinutes($eInvoiceRequestedDate) <= 60) && $supplier->e_invoice === 1) {
|
||||
$eInvoice = true;
|
||||
}
|
||||
$kvp = $booking->attributesKVP()->where('key', KVPKey::BOOKING_EINVOICE_ELIGIBLE)->first();
|
||||
if($kvp){
|
||||
$eInvoice = true;
|
||||
}
|
||||
|
||||
if($generateEInvoiceWithNormalInvoiceTemplate){
|
||||
$invoiceNo = ""; //July 2025 workaround generate normal invoice instead of E-Invoice
|
||||
}
|
||||
|
||||
if($invoiceNo){
|
||||
$billNumber = $invoiceNo;
|
||||
}
|
||||
else{
|
||||
$billNUmberPrefix = $eInvoice ? 'EINV-' : 'INV-';
|
||||
if($generateEInvoiceWithNormalInvoiceTemplate){
|
||||
$billNUmberPrefix = 'INV-'; //July 2025 workaround generate normal invoice instead of E-Invoice
|
||||
}
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute($billNUmberPrefix);
|
||||
}
|
||||
|
||||
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::PAYMENT, $generateEInvoiceRefund);
|
||||
|
||||
if($generateEInvoiceRefund){
|
||||
$total_service_charge = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereIn('status', [ApprovalStatus::REFUNDED])
|
||||
->sum('service_charge');
|
||||
|
||||
$total_tax = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereIn('status', [ApprovalStatus::REFUNDED])
|
||||
->sum('tax');
|
||||
}
|
||||
else{
|
||||
$total_service_charge = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
|
||||
->sum('service_charge');
|
||||
|
||||
$total_tax = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
|
||||
->sum('tax');
|
||||
}
|
||||
|
||||
$invoice_transaction = null;
|
||||
// if($booking->status === ApprovalStatus::APPROVED){
|
||||
// //NEW INVOICE for non-einvoice user applicable only when booking is completed
|
||||
// $invoice_transaction = $booking->transactions()
|
||||
// ->where('type', TransactionType::INVOICE)
|
||||
// ->complete()
|
||||
// ->latest()
|
||||
// ->first();
|
||||
// }
|
||||
|
||||
$invoice_transaction = null;
|
||||
if($booking->status === ApprovalStatus::APPROVED){
|
||||
//NEW INVOICE for non-einvoice user applicable only when booking is completed
|
||||
$invoice_transaction = $booking->transactions()
|
||||
->where('type', TransactionType::INVOICE)
|
||||
->whereIn('type', [TransactionType::INVOICE])
|
||||
->complete()
|
||||
->latest()
|
||||
->first();
|
||||
}
|
||||
|
||||
if(!$invoice_transaction) {
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::INVOICE,
|
||||
$transaction->issuer,
|
||||
$transaction->receiver,
|
||||
$transaction->recipient_bank_account_id,
|
||||
$transaction->payment_method,
|
||||
$payable_amount,
|
||||
$booking_amount,
|
||||
$transaction->currency_id,
|
||||
$transaction->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
$total_tax,
|
||||
$total_service_charge,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$invoice_transaction = $this->createsTransaction->execute($purchaseOrder->booking ?? $booking, $transaction_object);
|
||||
}
|
||||
|
||||
//Update booking table, used on Export Sales Invoice Report
|
||||
$booking->invoice_status = ApprovalStatus::APPROVED;
|
||||
$booking->save();
|
||||
|
||||
if ($kvpCopies) {
|
||||
foreach ($kvpCopies as $kvp) {
|
||||
$invoice_transaction->attributesKVP()->save($kvp);
|
||||
if(!$invoice_transaction) {
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::INVOICE,
|
||||
$transaction->issuer,
|
||||
$transaction->receiver,
|
||||
$transaction->recipient_bank_account_id,
|
||||
$transaction->payment_method,
|
||||
$payable_amount,
|
||||
$booking_amount,
|
||||
$transaction->currency_id,
|
||||
$transaction->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
$total_tax,
|
||||
$total_service_charge,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$invoice_transaction = $this->createsTransaction->execute($purchaseOrder->booking ?? $booking, $transaction_object);
|
||||
}
|
||||
}
|
||||
|
||||
$voucherRedemption = $transaction->voucherRedemption;
|
||||
|
||||
if($generateEInvoiceRefund){
|
||||
$metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first();
|
||||
if($metadata){
|
||||
$generateEInvoice = true;
|
||||
if ($kvpCopies) {
|
||||
foreach ($kvpCopies as $kvp) {
|
||||
$invoice_transaction->attributesKVP()->save($kvp);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$metadata = $transaction->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first();
|
||||
|
||||
$voucherRedemption = $transaction->voucherRedemption;
|
||||
|
||||
if($generateEInvoiceRefund){
|
||||
$metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first();
|
||||
if($metadata){
|
||||
$generateEInvoice = true;
|
||||
$generateEInvoice = true;
|
||||
}
|
||||
else{
|
||||
$metadata = $transaction->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first();
|
||||
if($metadata){
|
||||
$generateEInvoice = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($purchaseOrder){
|
||||
// purchase order
|
||||
if(!$generateEInvoiceRefund){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate);
|
||||
}
|
||||
|
||||
// deliver order
|
||||
if(!$generateEInvoiceRefund){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate);
|
||||
}
|
||||
|
||||
// e-invoice
|
||||
if ($eInvoice)
|
||||
{
|
||||
if($generateEInvoice){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund);
|
||||
}
|
||||
}
|
||||
// invoice
|
||||
else
|
||||
{
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund);
|
||||
}
|
||||
|
||||
if(!$generateEInvoiceRefund){
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('SPDO-');
|
||||
|
||||
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL, $generateEInvoiceRefund);
|
||||
|
||||
$paymentTransaction = $booking->transactions()->payments()->where('status', ApprovalStatus::COMPLETED)->first();
|
||||
|
||||
$transactionTypeBill= null;
|
||||
if($paymentTransaction){
|
||||
$transactionTypeBill = $paymentTransaction->transactions()->where('type', TransactionType::BILL)->first();
|
||||
}
|
||||
else{ // Special handling for refund cases (When a refund is deleted via DeleteRefundTransactionLogic, a booking payment transaction is set to ApprovalStatus::APPROVED)
|
||||
$paymentTransactionTemp = $booking->transactions()->payments()->where('status', ApprovalStatus::APPROVED)->first();
|
||||
|
||||
// Lets check if there is a full refund case
|
||||
if(!$paymentTransactionTemp){
|
||||
$paymentTransactionTemp = $booking->transactions()->payments()->where('status', ApprovalStatus::REFUNDED)->first();
|
||||
Log::info('CreateInvoiceTransactionV2Processor full refund: ' . json_encode($paymentTransactionTemp));
|
||||
}
|
||||
|
||||
// Lets check if there is a partial refund case
|
||||
$refund = $paymentTransactionTemp->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->first();
|
||||
if($refund){
|
||||
Log::info('CreateInvoiceTransactionV2Processor partial refund: ' . json_encode($refund));
|
||||
$transactionTypeBill = $paymentTransactionTemp->transactions()->where('type', TransactionType::BILL)->first();
|
||||
}
|
||||
else{
|
||||
Log::info("CreateInvoiceTransactionV2Processor NO completed payment transaction nor refund transaction found for booking '$booking->id'.");
|
||||
}
|
||||
}
|
||||
|
||||
if($transactionTypeBill){
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::SUPPLIER_DELIVER,
|
||||
$transactionTypeBill->issuer,
|
||||
$transactionTypeBill->receiver,
|
||||
$transactionTypeBill->recipient_bank_account_id,
|
||||
$transactionTypeBill->payment_method,
|
||||
$payable_amount,
|
||||
$booking_amount,
|
||||
$transactionTypeBill->currency_id,
|
||||
$transactionTypeBill->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
$total_tax,
|
||||
$total_service_charge,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$supplier_deliver_order_transaction = $this->createsTransaction->execute($purchaseOrder->booking, $transaction_object);
|
||||
|
||||
// supply deliver order
|
||||
$this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($purchaseOrder){
|
||||
// purchase order
|
||||
if(!$generateEInvoiceRefund){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate);
|
||||
}
|
||||
$this->updateStatuses($booking, $bookingOriginalStatus ?? 0);
|
||||
}
|
||||
|
||||
// deliver order
|
||||
if(!$generateEInvoiceRefund){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate);
|
||||
}
|
||||
//Update booking overall status and invoice status
|
||||
public function updateStatuses(Booking $booking, int $bookingStatus){
|
||||
$updateBookingInvoiceStatusObject = new UpdateBookingInvoiceStatusObject($booking->id, ApprovalStatus::APPROVED);
|
||||
$this->updatesBookingInvoiceStatus->execute($booking, $updateBookingInvoiceStatusObject);
|
||||
|
||||
// e-invoice
|
||||
if ($eInvoice)
|
||||
{
|
||||
if($generateEInvoice){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund);
|
||||
}
|
||||
}
|
||||
// invoice
|
||||
else
|
||||
{
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund);
|
||||
}
|
||||
|
||||
if(!$generateEInvoiceRefund){
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('SPDO-');
|
||||
|
||||
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL, $generateEInvoiceRefund);
|
||||
|
||||
$paymentTransaction = $booking->transactions()->payments()->where('status', ApprovalStatus::COMPLETED)->first();
|
||||
|
||||
$transactionTypeBill= null;
|
||||
if($paymentTransaction){
|
||||
$transactionTypeBill = $paymentTransaction->transactions()->where('type', TransactionType::BILL)->first();
|
||||
}
|
||||
else{ // Special handling for refund cases (When a refund is deleted via DeleteRefundTransactionLogic, a booking payment transaction is set to ApprovalStatus::APPROVED)
|
||||
$paymentTransactionTemp = $booking->transactions()->payments()->where('status', ApprovalStatus::APPROVED)->first();
|
||||
// Lets check if there is a refund case
|
||||
$refund = $paymentTransactionTemp->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->first();
|
||||
if($refund){
|
||||
$transactionTypeBill = $paymentTransactionTemp->transactions()->where('type', TransactionType::BILL)->first();
|
||||
}
|
||||
else{
|
||||
Log::info("CreateInvoiceTransactionV2Processor NO completed payment transaction nor refund transaction found for booking '$booking->id'.");
|
||||
}
|
||||
}
|
||||
|
||||
if($transactionTypeBill){
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::SUPPLIER_DELIVER,
|
||||
$transactionTypeBill->issuer,
|
||||
$transactionTypeBill->receiver,
|
||||
$transactionTypeBill->recipient_bank_account_id,
|
||||
$transactionTypeBill->payment_method,
|
||||
$payable_amount,
|
||||
$booking_amount,
|
||||
$transactionTypeBill->currency_id,
|
||||
$transactionTypeBill->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
$total_tax,
|
||||
$total_service_charge,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$supplier_deliver_order_transaction = $this->createsTransaction->execute($purchaseOrder->booking, $transaction_object);
|
||||
|
||||
// supply deliver order
|
||||
$this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER, null);
|
||||
}
|
||||
}
|
||||
|
||||
// update perfex crm
|
||||
// if(config('perfexcrm.is_enabled') == 'true'){
|
||||
// CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier);
|
||||
// }
|
||||
}
|
||||
|
||||
if($bookingOriginalStatus){
|
||||
$this->updatesBookingStatus->execute($booking, $bookingOriginalStatus);
|
||||
if($bookingStatus){
|
||||
$this->updatesBookingStatus->execute($booking, $bookingStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -13,8 +13,11 @@ use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
|
||||
use App\Classes\Modules\Transactions\Standards\Rules\CanUpdateRefundTransactionStatus;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Classes\ValueObjects\Constants\RemarkRefundReason;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Transaction;
|
||||
use ErrorException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UpdateRefundTransactionStatusProcessor
|
||||
@@ -107,6 +110,14 @@ class UpdateRefundTransactionStatusProcessor
|
||||
|
||||
$paidAmount = $paymentTransaction->original_amount - $refundAmount;
|
||||
|
||||
$claimed = Transaction::where('id', $refundTransaction->id)
|
||||
->where('process_status', null)
|
||||
->update(['process_status' => ApprovalStatus::PENDING_VERIFICATION]);
|
||||
|
||||
if (!$claimed) {
|
||||
throw new ErrorException("This refund transaction has already been processed");
|
||||
}
|
||||
|
||||
if ($refundTransaction->status == ApprovalStatus::APPROVED) {
|
||||
$this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference, $refundTransaction);
|
||||
|
||||
@@ -140,5 +151,9 @@ class UpdateRefundTransactionStatusProcessor
|
||||
'bookingOriginalStatus' => $booking->status
|
||||
]);
|
||||
}
|
||||
|
||||
Transaction::where('id', $refundTransaction->id)
|
||||
->where('process_status', ApprovalStatus::PENDING_VERIFICATION)
|
||||
->update(['process_status' => ApprovalStatus::APPROVED]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Standards\Rules;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\ValueObjects\Constants\RoleTypes;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanUpdateCreditNote extends AbstractRule
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
if (in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return bool
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return bool
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ use App\Classes\General\Eloquent\AbstractUpdateRecord;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Wallet;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UpdatesWalletBalance extends AbstractUpdateRecord
|
||||
{
|
||||
@@ -32,6 +33,15 @@ class UpdatesWalletBalance extends AbstractUpdateRecord
|
||||
}
|
||||
$auditBalance = ($topups + $credit) - ($payments + $debit);
|
||||
|
||||
Log::info('Wallet audit completed', [
|
||||
'wallet_id' => $model->id,
|
||||
'topups' => $topups,
|
||||
'credit' => $credit,
|
||||
'payments' => $payments,
|
||||
'debit' => $debit,
|
||||
'audit_balance' => $auditBalance,
|
||||
]);
|
||||
|
||||
$model->amount = $auditBalance;
|
||||
return $this->handler($model);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ class KVPKey
|
||||
public const AUTOCOUNT_EINVOICE_VALIDATION_LINK_CREDIT_NOTE = 'AUTOCOUNT_EINVOICE_VALIDATION_LINK_CN';
|
||||
|
||||
public const CREDIT_NOTE_APPROVAL_DATE = 'CREDIT_NOTE_APPROVAL_DATE';
|
||||
public const CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE = 'CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE';
|
||||
|
||||
public const TRANSACTION_MODEL_CLASS = 'App\Models\Transaction';
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands\V2;
|
||||
|
||||
|
||||
use App\Classes\Jobs\Commands\V2\CreateInvoiceTransactionV2CommandJob;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Booking;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class TestCreateEInvoiceV2Command extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
||||
protected $signature = 'test-create-einvoice-command';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Test Create E-Invoices';
|
||||
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// $bookings = Booking::whereIn('marking', ['644794'])->get();
|
||||
$bookings = Booking::whereIn('marking', ['507945'])->get();
|
||||
|
||||
$count = 0;
|
||||
foreach ($bookings as $booking) {
|
||||
CreateInvoiceTransactionV2CommandJob::dispatch($booking);
|
||||
$count++;
|
||||
Log::info('Processed: ' . $count);
|
||||
Log::info('Booking ID: ' . $booking->marking . ' for E-Invoice ');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use ZipArchive;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
//Commands Version 2: Laravel Vapor/AWS
|
||||
$isEnabled = env('COMMANDS_V2_ENABLED', false);
|
||||
if($isEnabled){
|
||||
// $schedule->command('dummy-command')
|
||||
// ->everyFiveMinutes()
|
||||
// ->withoutOverlapping();
|
||||
|
||||
$schedule->command('housekeeping-s3-files-command')
|
||||
->dailyAt('01:00')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('password-reset-token-expriration-check-command')
|
||||
->everySixHours()
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('new-user-registration-expire-check-command')
|
||||
->everySixHours()
|
||||
->withoutOverlapping();
|
||||
|
||||
if(env('APP_ENV') === 'production'){
|
||||
$schedule->command('email-do-to-vt-command')
|
||||
->dailyAt('10:00')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('seasonal-segmant-company-remove-command')
|
||||
->dailyAt('01:00')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('delete-bulk-download-files-command')
|
||||
->hourly()
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('booking-expired-command')
|
||||
->dailyAt('02:00')
|
||||
->withoutOverlapping();
|
||||
|
||||
// DISABLED BY DEFAULT
|
||||
// $schedule->command('purchase-order-autofill-command')
|
||||
// ->dailyAt('03:00')
|
||||
// ->withoutOverlapping();
|
||||
|
||||
// Push company module to Lark
|
||||
// $schedule->command('lark:push-company-module')
|
||||
// ->hourly()
|
||||
// ->withoutOverlapping();
|
||||
// // Push booking module to Lark
|
||||
// $schedule->command('lark:push-booking-module')
|
||||
// ->hourly()
|
||||
// ->withoutOverlapping();
|
||||
}
|
||||
}
|
||||
//Commands Version 1: Before Laravel Vapor/AWS
|
||||
else{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
$schedule->command('mail:EmailDoToVTCommand')->dailyAt('10:00')->withoutOverlapping();
|
||||
|
||||
$schedule->command('seasonalSegmantCompany:remove')
|
||||
->dailyAt('01:00')
|
||||
->appendOutputTo(storage_path().'/logs/soft-delete-seasonal-segmant-company.log')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('delete:bulk-download-files')
|
||||
->hourly()
|
||||
->appendOutputTo(storage_path().'/logs/delete-bulk-download-files.log')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('booking:expired')
|
||||
->dailyAt('02:00')
|
||||
->appendOutputTo(storage_path().'/logs/expire-booking.log')
|
||||
->withoutOverlapping();
|
||||
|
||||
// $schedule->command('purchaseOrder:autoFill')
|
||||
// ->dailyAt('03:00')
|
||||
// ->withoutOverlapping();
|
||||
}
|
||||
|
||||
// // Push booking module to Lark
|
||||
// $schedule->command('lark:push-booking-transactions-module')
|
||||
// ->everyTenMinutes();
|
||||
// $schedule->command('lark:push-booking-2025-transactions-module')
|
||||
// ->everyTenMinutes();
|
||||
$schedule->command('lark:push-booking-september-2025-transactions-module')
|
||||
->everyTenMinutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
use App\Classes\ValueObjects\Response\ApiResponseObject;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Foundation\Http\Exceptions\MaintenanceModeException;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Report or log an exception.
|
||||
*
|
||||
* @param \Throwable $exception
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function report(Throwable $exception)
|
||||
{
|
||||
parent::report($exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Throwable $exception
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function render($request, Throwable $exception)
|
||||
{
|
||||
if ($exception instanceof MaintenanceModeException) {
|
||||
return response()
|
||||
->view('pages.errors.maintenance');
|
||||
}
|
||||
|
||||
if ($exception instanceof AuthenticationException) {
|
||||
return (new ApiResponseObject('Authentication', 'To keep your account secure we need to re-validate your account', HttpStatus::ACCESS_UNAUTHORISED))->handler();
|
||||
}
|
||||
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ class AWSImageUploadController extends Controller
|
||||
public function imageUploadPost(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
|
||||
'image' => 'required|image:allow_svg|mimes:jpeg,png,jpg,gif,svg|max:2048',
|
||||
]);
|
||||
|
||||
$imageName = time().'.'.$request->image->extension();
|
||||
|
||||
@@ -169,7 +169,7 @@ class ImportStatementInvoiceController
|
||||
}
|
||||
|
||||
if ($transaction && $transaction->count() == 0) {
|
||||
$transaction = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where(DB::raw('FLOOR(statement_transactions.amount)'), floor($row['net_total']))->whereRaw("DATE(posting_date) = '$date'")->first();
|
||||
$transaction = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->whereRaw('FLOOR(statement_transactions.amount) = ?', [floor($row['net_total'])])->whereRaw("DATE(posting_date) = '$date'")->first();
|
||||
}
|
||||
|
||||
if ($transaction && $transaction->count() > 0) {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers\Transactions;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\UpdateCreditNoteOptLogic;
|
||||
|
||||
class UpdateCreditNoteOptController
|
||||
{
|
||||
public function opt(Request $request, UpdateCreditNoteOptLogic $logic) {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use App\Http\Middleware\Authenticate;
|
||||
use App\Http\Middleware\CheckForMaintenanceMode;
|
||||
use App\Http\Middleware\EncryptCookies;
|
||||
use App\Http\Middleware\RedirectIfAuthenticated;
|
||||
use App\Http\Middleware\TrimStrings;
|
||||
use App\Http\Middleware\TrustProxies;
|
||||
use App\Http\Middleware\ValidateToken;
|
||||
use App\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
CheckForMaintenanceMode::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
// \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\LogRequestPathMiddleware::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:300,1',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\LogRequestPathMiddleware::class,
|
||||
],
|
||||
|
||||
'apipub' => [
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\LogRequestPathMiddleware::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'valid.token' => ValidateToken::class,
|
||||
'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class,
|
||||
'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class, //cief maintenance
|
||||
];
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
@@ -19,5 +19,10 @@ class TrustProxies extends Middleware
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_PREFIX;
|
||||
}
|
||||
|
||||
@@ -7,23 +7,9 @@ use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
use App\Classes\ValueObjects\Response\ApiResponseObject;
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Tymon\JWTAuth\JWT;
|
||||
|
||||
class ValidateToken
|
||||
{
|
||||
/** @var JWT */
|
||||
private $manager;
|
||||
|
||||
/**
|
||||
* ValidateToken constructor.
|
||||
* @param JWT $manager
|
||||
*/
|
||||
public function __construct(JWT $manager)
|
||||
{
|
||||
$this->manager = $manager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if jwt token is valid.
|
||||
*
|
||||
@@ -35,9 +21,9 @@ class ValidateToken
|
||||
{
|
||||
try {
|
||||
|
||||
if(!$this->manager->check()){ throw new AccessUnauthorisedException(); }
|
||||
if(!auth('api')->check()){ throw new AccessUnauthorisedException(); }
|
||||
|
||||
} catch (Exception $exception) {
|
||||
} catch (Exception) {
|
||||
|
||||
return (new ApiResponseObject('Authentication', 'To keep your account secure we need to re-validate your account', HttpStatus::ACCESS_UNAUTHORISED))->handler();
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@ class TransactionResource extends JsonResource
|
||||
//Check if Transaction of type PAYMENT has an override for recipient bank - ends
|
||||
|
||||
$eInvoice = false;
|
||||
$manualOptInNormalCreditNote = false;
|
||||
|
||||
if($booking && $this->type === TransactionType::REFUND){
|
||||
$kvp = $this->attributesKVP()->where('key', KVPKey::TRANSACTION_MODEL_CLASS)->first();
|
||||
if($kvp){
|
||||
@@ -51,6 +53,12 @@ class TransactionResource extends JsonResource
|
||||
}
|
||||
}
|
||||
}
|
||||
$kvp = $this->attributesKVP()->where('key', KVPKey::CREDIT_NOTE_NORMAL_OPT_IN_OVERRIDE)->first();
|
||||
if($kvp){
|
||||
if($kvp->value == 1){
|
||||
$manualOptInNormalCreditNote = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1);
|
||||
@@ -90,6 +98,7 @@ class TransactionResource extends JsonResource
|
||||
'bank' => ((int) $this->type === TransactionType::PAYMENT) ? new BankResource($bank) : null, //When a transaction (of type payment) has an override recipient bank details on booking, this is NOT null
|
||||
'bank_recipient_edited' => $isEditedBankRecipient,
|
||||
'e_invoice' => $this->when($this->type === TransactionType::REFUND, $eInvoice),
|
||||
'manual_opt_in_normal_credit_note' => $this->when($this->type === TransactionType::REFUND, $manualOptInNormalCreditNote),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace App\Logging;
|
||||
|
||||
use Aws\CloudWatchLogs\CloudWatchLogsClient;
|
||||
use Maxbanton\Cwh\Handler\CloudWatch;
|
||||
use PhpNexus\Cwh\Handler\CloudWatch;
|
||||
use Monolog\Formatter\JsonFormatter;
|
||||
use Monolog\Logger;
|
||||
|
||||
|
||||
@@ -6,12 +6,21 @@ namespace App\Models;
|
||||
use App\Classes\General\Interfaces\Notifiable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
use Spatie\Activitylog\LogOptions;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
class AbstractModel extends Model implements Notifiable
|
||||
{
|
||||
use LogsActivity;
|
||||
protected static $logFillable = true;
|
||||
|
||||
/**
|
||||
* Get the options for logging activity.
|
||||
*/
|
||||
public function getActivitylogOptions(): LogOptions
|
||||
{
|
||||
return LogOptions::defaults()
|
||||
->logFillable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MorphTo
|
||||
@@ -36,4 +45,4 @@ class AbstractModel extends Model implements Notifiable
|
||||
{
|
||||
return $this->MorphTo('causer');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,18 @@ class AccountStatement extends Model
|
||||
'mapped_rows',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'date_from' => 'date',
|
||||
'date_to' => 'date',
|
||||
];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'date_from' => 'date',
|
||||
'date_to' => 'date',
|
||||
];
|
||||
}
|
||||
|
||||
public function account()
|
||||
{
|
||||
|
||||
+21
-11
@@ -9,22 +9,32 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
* Class Address
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Country country_id
|
||||
* @property \App\Models\Company company_id
|
||||
* @property \App\Models\State state_id
|
||||
* @property \App\Models\District district_id
|
||||
* @property string postcode
|
||||
* @property string street_one
|
||||
* @property string street_two
|
||||
* @property integer billing_type
|
||||
* @property int $country_id
|
||||
* @property int $company_id
|
||||
* @property int $state_id
|
||||
* @property int $district_id
|
||||
* @property string $postcode
|
||||
* @property string $street_one
|
||||
* @property string $street_two
|
||||
* @property int $billing_type
|
||||
*/
|
||||
class Address extends AbstractModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'addresses';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
@@ -64,6 +74,6 @@ class Address extends AbstractModel
|
||||
*/
|
||||
public function scopeDefault(Builder $query)
|
||||
{
|
||||
return $query->where('billing', '=',true)->first();
|
||||
return $query->where('billing', '=', true)->first();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ class Affiliate extends AbstractModel
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'affiliates';
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
protected $fillable = [
|
||||
'code',
|
||||
@@ -24,12 +23,21 @@ class Affiliate extends AbstractModel
|
||||
'orders_count'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_active' => 'boolean',
|
||||
'clicks_count' => 'integer',
|
||||
'registrations_count' => 'integer',
|
||||
'orders_count' => 'integer'
|
||||
];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'is_active' => 'boolean',
|
||||
'clicks_count' => 'integer',
|
||||
'registrations_count' => 'integer',
|
||||
'orders_count' => 'integer',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
/**
|
||||
* Class Announcement
|
||||
* @package App\Models
|
||||
*
|
||||
*/
|
||||
class Announcement extends AbstractModel
|
||||
{
|
||||
@@ -16,9 +15,6 @@ class Announcement extends AbstractModel
|
||||
|
||||
protected $table = 'announcements';
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
**/
|
||||
public function segments(): BelongsToMany
|
||||
{
|
||||
return $this->BelongsToMany(Segment::class);
|
||||
|
||||
+9
-10
@@ -14,22 +14,21 @@ use App\Classes\General\Interfaces\KeyValueInterface;
|
||||
* Class Bank
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Country country_id
|
||||
* @property \App\Models\Company company_id
|
||||
* @property string bank_name
|
||||
* @property string holder_name
|
||||
* @property string account_no
|
||||
* @property int type
|
||||
* @property int default
|
||||
* @property int status
|
||||
* @property int $country_id
|
||||
* @property int $company_id
|
||||
* @property string $bank_name
|
||||
* @property string $holder_name
|
||||
* @property string $account_no
|
||||
* @property int $type
|
||||
* @property int $default
|
||||
* @property int $status
|
||||
*/
|
||||
class Bank extends AbstractModel implements KeyValueInterface
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'company_id',
|
||||
|
||||
@@ -19,7 +19,17 @@ class BillGroup extends Model implements Documentable, Transactionable
|
||||
|
||||
protected $table = 'bill_groups';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MorphMany
|
||||
|
||||
+19
-9
@@ -19,13 +19,13 @@ use Staudenmeir\EloquentHasManyDeep\HasRelationships;
|
||||
* Class Booking
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Company company_id
|
||||
* @property \App\Models\Bank transferable_bank_id
|
||||
* @property string marking
|
||||
* @property string reference
|
||||
* @property float fix_amount
|
||||
* @property int convertible_currency_id
|
||||
* @property int conversion_currency_id
|
||||
* @property int $company_id
|
||||
* @property int $transferable_bank_id
|
||||
* @property string $marking
|
||||
* @property string $reference
|
||||
* @property float $fix_amount
|
||||
* @property int $convertible_currency_id
|
||||
* @property int $conversion_currency_id
|
||||
*/
|
||||
class Booking extends AbstractModel implements Documentable, Transactionable, Voucherifiable, KeyValueInterface
|
||||
{
|
||||
@@ -35,7 +35,17 @@ class Booking extends AbstractModel implements Documentable, Transactionable, Vo
|
||||
|
||||
protected $table = 'bookings';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
@@ -106,7 +116,7 @@ class Booking extends AbstractModel implements Documentable, Transactionable, Vo
|
||||
*/
|
||||
public function bills(): hasManyDeep
|
||||
{
|
||||
return $this->hasManyDeep(Transaction::class, [Transaction::class.' as alias'], [['owner_type', 'owner_id'], ['owner_type', 'owner_id']], [null, null]);
|
||||
return $this->hasManyDeep(Transaction::class, [Transaction::class . ' as alias'], [['owner_type', 'owner_id'], ['owner_type', 'owner_id']], [null, null]);
|
||||
}
|
||||
|
||||
public function modelAttributes(): MorphMany
|
||||
|
||||
+19
-9
@@ -20,13 +20,13 @@ use Staudenmeir\EloquentHasManyDeep\HasRelationships;
|
||||
* Class Company
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Country country_id
|
||||
* @property \App\Models\State state_id
|
||||
* @property \App\Models\District district_id
|
||||
* @property string postcode
|
||||
* @property string street_one
|
||||
* @property string street_two
|
||||
* @property integer billing_type
|
||||
* @property int $country_id
|
||||
* @property int $state_id
|
||||
* @property int $district_id
|
||||
* @property string $postcode
|
||||
* @property string $street_one
|
||||
* @property string $street_two
|
||||
* @property int $billing_type
|
||||
*/
|
||||
class Company extends AbstractModel implements Documentable
|
||||
{
|
||||
@@ -35,8 +35,18 @@ class Company extends AbstractModel implements Documentable
|
||||
|
||||
protected $table = 'companies';
|
||||
|
||||
protected $dates = ['deleted_at', 'created_at'];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
'created_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany
|
||||
|
||||
+19
-12
@@ -10,12 +10,12 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* Class Contact
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Country country_id
|
||||
* @property \App\Models\Company company_id
|
||||
* @property string reference
|
||||
* @property string phone
|
||||
* @property string email
|
||||
* @property string wechat_id
|
||||
* @property int $country_id
|
||||
* @property int $company_id
|
||||
* @property string $reference
|
||||
* @property string $phone
|
||||
* @property string $email
|
||||
* @property string $wechat_id
|
||||
*/
|
||||
class Contact extends AbstractModel
|
||||
{
|
||||
@@ -23,20 +23,27 @@ class Contact extends AbstractModel
|
||||
|
||||
protected $table = 'contacts';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
**/
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function company(): HasOne
|
||||
{
|
||||
return $this->hasOne(Company::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return belongsTo
|
||||
* @return BelongsTo
|
||||
**/
|
||||
public function country(): belongsTo
|
||||
public function country(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Country::class);
|
||||
}
|
||||
|
||||
+14
-4
@@ -9,9 +9,9 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* Class Country
|
||||
* @package App\Models
|
||||
*
|
||||
* @property string name
|
||||
* @property string short_code
|
||||
* @property string phone_code
|
||||
* @property string $name
|
||||
* @property string $short_code
|
||||
* @property string $phone_code
|
||||
*/
|
||||
class Country extends AbstractModel
|
||||
{
|
||||
@@ -19,7 +19,17 @@ class Country extends AbstractModel
|
||||
|
||||
protected $table = 'countries';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected $fillable = ['name', 'short_code', 'phone_code'];
|
||||
|
||||
|
||||
+18
-8
@@ -6,16 +6,16 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\hasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* Class Currency
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Country country_id
|
||||
* @property string name
|
||||
* @property string short_code
|
||||
* @property string symbol
|
||||
* @property int $country_id
|
||||
* @property string $name
|
||||
* @property string $short_code
|
||||
* @property string $symbol
|
||||
*/
|
||||
|
||||
class Currency extends AbstractModel
|
||||
@@ -24,7 +24,17 @@ class Currency extends AbstractModel
|
||||
|
||||
protected $table = 'currencies';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
@@ -35,9 +45,9 @@ class Currency extends AbstractModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @return hasMany
|
||||
* @return HasMany
|
||||
*/
|
||||
public function rates(): hasMany
|
||||
public function rates(): HasMany
|
||||
{
|
||||
return $this->hasMany(CurrencyRate::class, 'currency_id');
|
||||
}
|
||||
|
||||
@@ -12,5 +12,15 @@ class CurrencyRate extends AbstractModel
|
||||
|
||||
protected $fillable = ['currency_id', 'selling', 'payment_method_type'];
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
+15
-5
@@ -10,10 +10,10 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* Class District
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Country country_id
|
||||
* @property \App\Models\State state_id
|
||||
* @property string name
|
||||
* @property string postcode
|
||||
* @property int $country_id
|
||||
* @property int $state_id
|
||||
* @property string $name
|
||||
* @property string $postcode
|
||||
*/
|
||||
class District extends AbstractModel
|
||||
{
|
||||
@@ -21,7 +21,17 @@ class District extends AbstractModel
|
||||
|
||||
protected $table = 'districts';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
|
||||
+24
-15
@@ -7,22 +7,21 @@ use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\hasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* Class Document
|
||||
* @package App\Models
|
||||
* @version August 4, 2020, 4:36 am
|
||||
*
|
||||
* @property int owner_id
|
||||
* @property int owner_type
|
||||
* @property int document_type
|
||||
* @property string reference
|
||||
* @property int status
|
||||
* @property \App\Models\User approver
|
||||
* @property timestamp issued_date
|
||||
* @property timestamp expired_date
|
||||
* @property timestamp approved_date
|
||||
* @property int $owner_id
|
||||
* @property int $owner_type
|
||||
* @property int $document_type
|
||||
* @property string $reference
|
||||
* @property int $status
|
||||
* @property int $approver
|
||||
* @property string $issued_date
|
||||
* @property string $expired_date
|
||||
* @property string $approved_date
|
||||
*/
|
||||
class Document extends AbstractModel
|
||||
{
|
||||
@@ -30,7 +29,17 @@ class Document extends AbstractModel
|
||||
|
||||
protected $table = 'documents';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
@@ -41,9 +50,9 @@ class Document extends AbstractModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @return hasMany
|
||||
* @return HasMany
|
||||
*/
|
||||
public function files(): hasMany
|
||||
public function files(): HasMany
|
||||
{
|
||||
return $this->hasMany(File::class, 'document_id');
|
||||
}
|
||||
@@ -51,7 +60,7 @@ class Document extends AbstractModel
|
||||
/**
|
||||
* @return HasOne
|
||||
*/
|
||||
public function approver(): hasOne
|
||||
public function approver(): HasOne
|
||||
{
|
||||
return $this->hasOne(User::class, 'id', 'approver');
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
/**
|
||||
* Class CompanyEmployee
|
||||
* Class Employee
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Company company_id
|
||||
* @property \App\Models\User user_id
|
||||
* @property int $company_id
|
||||
* @property int $user_id
|
||||
*/
|
||||
class Employee extends AbstractModel
|
||||
{
|
||||
@@ -24,9 +24,6 @@ class Employee extends AbstractModel
|
||||
return $this->HasMany(Company::class, 'company_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
**/
|
||||
public function user(): HasOne
|
||||
{
|
||||
return $this->hasOne(User::class, 'user_id', 'id');
|
||||
|
||||
+13
-8
@@ -8,11 +8,10 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
/**
|
||||
* Class File
|
||||
* @package App\Models
|
||||
* @version August 4, 2020, 4:36 am
|
||||
*
|
||||
* @property \App\Models\Document document_id
|
||||
* @property text file
|
||||
* @property int file_type_id
|
||||
* @property int $document_id
|
||||
* @property object $file
|
||||
* @property int $file_type_id
|
||||
*/
|
||||
class File extends AbstractModel
|
||||
{
|
||||
@@ -22,10 +21,16 @@ class File extends AbstractModel
|
||||
|
||||
protected $fillable = ['file'];
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
public function getFileAttribute($value)
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return $value ? json_decode($value) : [];
|
||||
return [
|
||||
'file' => 'object',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,6 @@ class KeyValuePair extends AbstractModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
protected $table = 'key_value_pairs';
|
||||
|
||||
protected $fillable = [
|
||||
@@ -19,6 +17,18 @@ class KeyValuePair extends AbstractModel
|
||||
'value',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function owner(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
|
||||
@@ -8,7 +8,18 @@ class Milestone extends AbstractModel
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'milestones';
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function progress()
|
||||
{
|
||||
|
||||
@@ -9,7 +9,18 @@ class MilestoneProgress extends AbstractModel
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'milestone_progress';
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function milestone()
|
||||
{
|
||||
|
||||
@@ -15,9 +15,17 @@ class ModelAttribute extends Model
|
||||
"value"
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
"value" => "array"
|
||||
];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
"value" => "array",
|
||||
];
|
||||
}
|
||||
|
||||
public function owner(): morphTo
|
||||
{
|
||||
|
||||
+12
-1
@@ -10,7 +10,18 @@ class Reward extends AbstractModel
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'rewards';
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function milestones()
|
||||
{
|
||||
|
||||
@@ -11,13 +11,13 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
* Class SeasonalSegment
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Company company_id
|
||||
* @property \App\Models\Bank transferable_bank_id
|
||||
* @property string marking
|
||||
* @property string reference
|
||||
* @property float fix_amount
|
||||
* @property int convertible_currency_id
|
||||
* @property int conversion_currency_id
|
||||
* @property int $company_id
|
||||
* @property int $transferable_bank_id
|
||||
* @property string $marking
|
||||
* @property string $reference
|
||||
* @property float $fix_amount
|
||||
* @property int $convertible_currency_id
|
||||
* @property int $conversion_currency_id
|
||||
*/
|
||||
class SeasonalSegment extends Model
|
||||
{
|
||||
@@ -27,11 +27,19 @@ class SeasonalSegment extends Model
|
||||
|
||||
protected $table = 'seasonal_segment';
|
||||
|
||||
protected $dates = [
|
||||
'starting_on',
|
||||
'ending_on',
|
||||
'deleted_at',
|
||||
];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'starting_on' => 'datetime',
|
||||
'ending_on' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
|
||||
+13
-3
@@ -9,8 +9,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* Class Segment
|
||||
* @package App\Models
|
||||
*
|
||||
* @property string name
|
||||
* @property string reference
|
||||
* @property string $name
|
||||
* @property string $reference
|
||||
*/
|
||||
class Segment extends AbstractModel
|
||||
{
|
||||
@@ -18,7 +18,17 @@ class Segment extends AbstractModel
|
||||
|
||||
protected $table = 'segments';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany
|
||||
|
||||
@@ -10,8 +10,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* Class SegmentConstant
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Segment segment_id
|
||||
* @property string detail
|
||||
* @property int $segment_id
|
||||
* @property object $detail
|
||||
*/
|
||||
class SegmentConstant extends AbstractModel
|
||||
{
|
||||
@@ -19,15 +19,17 @@ class SegmentConstant extends AbstractModel
|
||||
|
||||
protected $table = 'segment_constants';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
// protected $casts = [
|
||||
// 'detail' => 'array',
|
||||
// ];
|
||||
|
||||
public function getDetailAttribute($value)
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return $value ? json_decode($value) : [];
|
||||
return [
|
||||
'detail' => 'object',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+15
-15
@@ -13,7 +13,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @package App\Models
|
||||
* @version February 16, 2021, 9:04 pm
|
||||
*
|
||||
* @property string name
|
||||
* @property string $name
|
||||
*/
|
||||
class ServiceType extends AbstractModel
|
||||
{
|
||||
@@ -23,46 +23,46 @@ class ServiceType extends AbstractModel
|
||||
|
||||
protected $table = 'service_types';
|
||||
|
||||
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
|
||||
|
||||
public $fillable = [
|
||||
'name'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be casted to native types.
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'name' => 'string'
|
||||
];
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'string',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation rules
|
||||
*
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public static $rules = [
|
||||
'name' => 'required'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return hasMany
|
||||
* @return HasMany
|
||||
*/
|
||||
public function rates(): hasMany
|
||||
public function rates(): HasMany
|
||||
{
|
||||
return $this->hasMany(CurrencyRate::class, 'service_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return hasMany
|
||||
* @return HasMany
|
||||
*/
|
||||
public function constants(): hasMany
|
||||
public function constants(): HasMany
|
||||
{
|
||||
return $this->hasMany(SegmentConstant::class, 'detail->id')
|
||||
->whereIn('reference', [SegmentConstants::SERVICE_TYPE, SegmentConstants::CUSTOM_SERVICE_TYPE]);
|
||||
|
||||
+13
-3
@@ -9,8 +9,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* Class State
|
||||
* @package App\Models
|
||||
*
|
||||
* @property \App\Models\Country country_id
|
||||
* @property string name
|
||||
* @property int $country_id
|
||||
* @property string $name
|
||||
*/
|
||||
class State extends AbstractModel
|
||||
{
|
||||
@@ -18,7 +18,17 @@ class State extends AbstractModel
|
||||
|
||||
protected $table = 'states';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasOne
|
||||
|
||||
@@ -30,9 +30,17 @@ class StatementTransaction extends Model
|
||||
'end_balance',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'posting_date' => 'datetime',
|
||||
];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'posting_date' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function account()
|
||||
{
|
||||
|
||||
@@ -29,12 +29,20 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
|
||||
use SoftDeletes;
|
||||
use LogData;
|
||||
|
||||
protected $casts = [
|
||||
'type' => 'int'
|
||||
];
|
||||
|
||||
protected $table = 'transactions';
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'type' => 'int',
|
||||
];
|
||||
}
|
||||
|
||||
public function owner(): morphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
|
||||
@@ -9,9 +9,17 @@ class TransactionMappingLog extends Model
|
||||
{
|
||||
protected $fillable = ['imported_by','data','imported_date','type'];
|
||||
|
||||
protected $casts = [
|
||||
'data' => 'array',
|
||||
];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'data' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
public static function boot() {
|
||||
parent::boot();
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ class User extends AbstractModel implements
|
||||
return $this->HasMany(UserReward::class, 'user_id', 'id');
|
||||
}
|
||||
|
||||
public function hasAttribute(string $key, $value = null): bool
|
||||
public function hasCustomAttribute(string $key, $value = null): bool
|
||||
{
|
||||
$query = $this->attributesKVP()->where('key', $key);
|
||||
|
||||
|
||||
@@ -15,10 +15,18 @@ class UserAffiliate extends AbstractModel
|
||||
'registered_at'
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'clicked_at',
|
||||
'registered_at'
|
||||
];
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'clicked_at' => 'datetime',
|
||||
'registered_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
|
||||
@@ -9,7 +9,18 @@ class UserReward extends AbstractModel
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'user_rewards';
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function reward()
|
||||
{
|
||||
|
||||
@@ -10,7 +10,18 @@ class VoucherEntityMapping extends AbstractModel
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'voucher_entity_mappings';
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
|
||||
@@ -4,6 +4,9 @@ namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -27,5 +30,10 @@ class AppServiceProvider extends ServiceProvider
|
||||
if (!file_exists(storage_path('framework/sessions'))) {
|
||||
mkdir(storage_path('framework/sessions'), 0777, true);
|
||||
}
|
||||
|
||||
//From Shipping Portal
|
||||
// RateLimiter::for('api', function (Request $request) {
|
||||
// return Limit::perMinute(300)->by($request->user()?->id ?: $request->ip());
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* This namespace is applied to your controller routes.
|
||||
*
|
||||
* In addition, it is set as the URL generator's root namespace.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = 'App\Http\Controllers';
|
||||
|
||||
/**
|
||||
* The path to the "home" route for your application.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/home';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function map()
|
||||
{
|
||||
$this->mapApiRoutes();
|
||||
|
||||
$this->mapWebRoutes();
|
||||
|
||||
$this->mapApiPubRoutes();
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "web" routes for the application.
|
||||
*
|
||||
* These routes all receive session state, CSRF protection, etc.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mapWebRoutes()
|
||||
{
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web.php'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "api" routes for the application.
|
||||
*
|
||||
* These routes are typically stateless.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mapApiRoutes()
|
||||
{
|
||||
Route::prefix('api')
|
||||
->middleware('api')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/api.php'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "apipub" routes for the application.
|
||||
*
|
||||
* These routes are typically stateless.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mapApiPubRoutes()
|
||||
{
|
||||
Route::prefix('public/api')
|
||||
->middleware('apipub')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/apipub.php'));
|
||||
}
|
||||
}
|
||||
+146
-46
@@ -1,55 +1,155 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Create The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The first thing we will do is create a new Laravel application instance
|
||||
| which serves as the "glue" for all the components of Laravel, and is
|
||||
| the IoC container for the system binding all of the various parts.
|
||||
|
|
||||
*/
|
||||
use App\Http\Middleware\ValidateToken;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
use App\Classes\ValueObjects\Response\ApiResponseObject;
|
||||
|
||||
$app = new Illuminate\Foundation\Application(
|
||||
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
|
||||
);
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
->withRouting(
|
||||
web: __DIR__ . '/../routes/web.php',
|
||||
api: __DIR__ . '/../routes/api.php',
|
||||
commands: __DIR__ . '/../routes/console.php',
|
||||
health: '/up',
|
||||
then: function () {
|
||||
// Load public API routes (not loaded in api.php)
|
||||
Route::middleware('apipub')
|
||||
->prefix('public/api')
|
||||
->group(base_path('routes/apipub.php'));
|
||||
},
|
||||
)
|
||||
->withMiddleware(function (Middleware $middleware) {
|
||||
// '*' trusts all proxies, required for correct IP/HTTPS detection behind AWS ALB/Vapor
|
||||
$middleware->trustProxies(at: '*');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Bind Important Interfaces
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Next, we need to bind some important interfaces into the container so
|
||||
| we will be able to resolve them when needed. The kernels serve the
|
||||
| incoming requests to this application from both the web and CLI.
|
||||
|
|
||||
*/
|
||||
$middleware->web(append: [
|
||||
\App\Http\Middleware\LogRequestPathMiddleware::class,
|
||||
]);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Http\Kernel::class,
|
||||
App\Http\Kernel::class
|
||||
);
|
||||
$middleware->api(append: [
|
||||
\App\Http\Middleware\LogRequestPathMiddleware::class,
|
||||
]);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Console\Kernel::class,
|
||||
App\Console\Kernel::class
|
||||
);
|
||||
$middleware->api(prepend: [
|
||||
'throttle:300,1',
|
||||
]);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Debug\ExceptionHandler::class,
|
||||
App\Exceptions\Handler::class
|
||||
);
|
||||
$middleware->validateCsrfTokens(except: [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Return The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This script returns the application instance. The instance is given to
|
||||
| the calling script so we can separate the building of the instances
|
||||
| from the actual running of the application and sending responses.
|
||||
|
|
||||
*/
|
||||
]);
|
||||
|
||||
return $app;
|
||||
$middleware->alias([
|
||||
'valid.token' => ValidateToken::class,
|
||||
'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class,
|
||||
'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class,
|
||||
]);
|
||||
|
||||
$middleware->appendToGroup('apipub', [
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\LogRequestPathMiddleware::class,
|
||||
]);
|
||||
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions) {
|
||||
// Custom exception rendering
|
||||
// $exceptions->render(function (MaintenanceModeException $e, $request) {
|
||||
// return response()->view('pages.errors.maintenance');
|
||||
// });
|
||||
|
||||
$exceptions->render(function (AuthenticationException $e, $request) {
|
||||
return (new ApiResponseObject(
|
||||
'Authentication',
|
||||
'To keep your account secure, we need to re-validate it.',
|
||||
HttpStatus::ACCESS_UNAUTHORISED
|
||||
))->handler();
|
||||
});
|
||||
|
||||
// Don't flash these inputs
|
||||
$exceptions->dontFlash([
|
||||
'password',
|
||||
'password_confirmation',
|
||||
]);
|
||||
})
|
||||
->withCommands([
|
||||
__DIR__ . '/../app/Console/Commands',
|
||||
__DIR__ . '/../app/Console/Commands/V2',
|
||||
])
|
||||
->withSchedule(function ($schedule) {
|
||||
// Commands Version 2: Laravel Vapor/AWS
|
||||
$isEnabled = env('COMMANDS_V2_ENABLED', false);
|
||||
if ($isEnabled) {
|
||||
$schedule->command('housekeeping-s3-files-command')
|
||||
->dailyAt('01:00')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('password-reset-token-expriration-check-command')
|
||||
->everySixHours()
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('new-user-registration-expire-check-command')
|
||||
->everySixHours()
|
||||
->withoutOverlapping();
|
||||
|
||||
if (env('APP_ENV') === 'production') {
|
||||
$schedule->command('email-do-to-vt-command')
|
||||
->dailyAt('10:00')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('seasonal-segmant-company-remove-command')
|
||||
->dailyAt('01:00')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('delete-bulk-download-files-command')
|
||||
->hourly()
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('booking-expired-command')
|
||||
->dailyAt('02:00')
|
||||
->withoutOverlapping();
|
||||
|
||||
// Push company module to Lark
|
||||
$schedule->command('lark:push-company-module')
|
||||
->hourly()
|
||||
->withoutOverlapping();
|
||||
|
||||
// Push booking module to Lark
|
||||
$schedule->command('lark:push-booking-module')
|
||||
->hourly()
|
||||
->withoutOverlapping();
|
||||
|
||||
// // Push booking module to Lark
|
||||
// $schedule->command('lark:push-booking-transactions-module')
|
||||
// ->everyTenMinutes();
|
||||
// $schedule->command('lark:push-booking-2025-transactions-module')
|
||||
// ->everyTenMinutes();
|
||||
// $schedule->command('lark:push-booking-september-2025-transactions-module')
|
||||
// ->everyTenMinutes();
|
||||
}
|
||||
}
|
||||
// Commands Version 1: Before Laravel Vapor/AWS
|
||||
else {
|
||||
$schedule->command('mail:EmailDoToVTCommand')
|
||||
->dailyAt('10:00')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('seasonalSegmantCompany:remove')
|
||||
->dailyAt('01:00')
|
||||
->appendOutputTo(storage_path() . '/logs/soft-delete-seasonal-segmant-company.log')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('delete:bulk-download-files')
|
||||
->hourly()
|
||||
->appendOutputTo(storage_path() . '/logs/delete-bulk-download-files.log')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('booking:expired')
|
||||
->dailyAt('02:00')
|
||||
->appendOutputTo(storage_path() . '/logs/expire-booking.log')
|
||||
->withoutOverlapping();
|
||||
}
|
||||
})
|
||||
->create();
|
||||
|
||||
+22
-24
@@ -8,52 +8,50 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"php": "^8.3",
|
||||
"ext-bcmath": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"barryvdh/laravel-dompdf": "^0.9.0",
|
||||
"barryvdh/laravel-dompdf": "^3.1",
|
||||
"carlos-meneses/laravel-mpdf": "^2.1",
|
||||
"doctrine/dbal": "^2.12.1",
|
||||
"fideloper/proxy": "^4.2",
|
||||
"fruitcake/laravel-cors": "^1.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"intervention/image": "^2.5",
|
||||
"doctrine/dbal": "^3.0|^4.0",
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"intervention/image": "^2.7|^3.0",
|
||||
"kwn/number-to-words": "^2.11",
|
||||
"laravel/framework": "^8.0",
|
||||
"laravel/tinker": "^2.0",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/tinker": "^2.9",
|
||||
"laravel/vapor-cli": "^1.55",
|
||||
"laravel/vapor-core": "^2.33",
|
||||
"league/flysystem-aws-s3-v3": "^3.0",
|
||||
"maatwebsite/excel": "^3.1",
|
||||
"maxbanton/cwh": "^2.0",
|
||||
"phpnexus/cwh": "^3.0",
|
||||
"mpdf/mpdf": "^8.1",
|
||||
"pusher/pusher-php-server": "^7.2",
|
||||
"rinvex/countries": "^6.1",
|
||||
"rinvex/countries": "^9.0",
|
||||
"rspective/voucherify": " v2.0.*",
|
||||
"smalot/pdfparser": "^2.2",
|
||||
"spatie/laravel-activitylog": "^3.14",
|
||||
"spatie/laravel-permission": "^3.17",
|
||||
"spatie/laravel-activitylog": "^4.10",
|
||||
"spatie/laravel-permission": "^7.0",
|
||||
"staudenmeir/eloquent-has-many-deep": "^1.7",
|
||||
"timehunter/laravel-google-recaptcha-v3": "~2.5",
|
||||
"tymon/jwt-auth": "^1.0",
|
||||
"symfony/http-client": "^7.4",
|
||||
"symfony/mailgun-mailer": "^7.4",
|
||||
"tymon/jwt-auth": "^2.0",
|
||||
"webklex/laravel-pdfmerger": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^2.3.6",
|
||||
"fzaninotto/faker": "^1.9.1",
|
||||
"laravel/dusk": "^6.23",
|
||||
"mockery/mockery": "^1.3.1",
|
||||
"nunomaduro/collision": "^5.0",
|
||||
"phpunit/phpunit": "^9.0"
|
||||
"fakerphp/faker": "^1.20",
|
||||
"laravel/dusk": "^8.0",
|
||||
"mockery/mockery": "^1.5",
|
||||
"nunomaduro/collision": "^8.5",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
"spatie/laravel-ignition": "^2.5"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true,
|
||||
"audit": {
|
||||
"block-insecure": false
|
||||
}
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
|
||||
+1
-2
@@ -173,7 +173,6 @@ return [
|
||||
App\Providers\AuthServiceProvider::class,
|
||||
// App\Providers\BroadcastServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
|
||||
// Third Parties
|
||||
Spatie\Permission\PermissionServiceProvider::class,
|
||||
@@ -233,7 +232,7 @@ return [
|
||||
'URL' => Illuminate\Support\Facades\URL::class,
|
||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
'PDF' => Barryvdh\DomPDF\Facade::class,
|
||||
'PDF' => Barryvdh\DomPDF\Facade\Pdf::class,
|
||||
'MPDF' => Mccarlosen\LaravelMpdf\Facades\LaravelMpdf::class,
|
||||
'GoogleReCaptchaV3'=> TimeHunter\LaravelGoogleReCaptchaV3\Facades\GoogleReCaptchaV3::class,
|
||||
'PDFMerger' => Webklex\PDFMerger\Facades\PDFMergerFacade::class
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'paths' => ['api/*'],
|
||||
'paths' => ['api/*', 'public/api/*'],
|
||||
|
||||
'allowed_methods' => ['*'],
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('FILESYSTEM_DRIVER', 'local'),
|
||||
'default' => env('FILESYSTEM_DISK', env('FILESYSTEM_DRIVER', 'local')),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -45,7 +45,7 @@ return [
|
||||
|
||||
'local' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app'),
|
||||
'root' => storage_path('app/private'),
|
||||
],
|
||||
|
||||
'public' => [
|
||||
|
||||
@@ -49,4 +49,17 @@ return [
|
||||
'time' => 2,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Rehashing on Login
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When enabled, passwords will be automatically rehashed during
|
||||
| authentication if the hashing algorithm's work factor has changed.
|
||||
| This ensures passwords stay secure as hardware improves.
|
||||
|
|
||||
*/
|
||||
|
||||
'rehash_on_login' => true,
|
||||
|
||||
];
|
||||
|
||||
@@ -20,7 +20,7 @@ class CreateBookingsTable extends Migration
|
||||
$table->string('marking')->unique();
|
||||
$table->foreignId('service_id')->unsigned();
|
||||
$table->foreignId('bank_id')->unsigned();
|
||||
$table->float('fix_amount', 20, 5);
|
||||
$table->decimal('fix_amount', 20, 5);
|
||||
$table->foreignId('fix_currency_id')->unsigned();
|
||||
$table->foreignId('convertible_currency_id')->unsigned();
|
||||
$table->foreignId('conversion_currency_id')->unsigned();
|
||||
|
||||
@@ -24,7 +24,7 @@ class CreateStatementTransactionsTable extends Migration
|
||||
$table->string('transaction_description_4')->nullable();
|
||||
$table->string('transaction_description_5')->nullable();
|
||||
$table->string('transaction_ref')->nullable();
|
||||
$table->float('amount', 15, 2)->unsigned(false);
|
||||
$table->decimal('amount', 15, 2)->unsigned(false);
|
||||
$table->string('teller_id')->nullable();
|
||||
$table->string('branch_channel');
|
||||
$table->string('transaction_code');
|
||||
|
||||
@@ -13,11 +13,13 @@ class AddInvoiceStatusToBookingLogsTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->boolean('invoice_status')
|
||||
->default(false)
|
||||
->after('status');
|
||||
});
|
||||
if (Schema::hasTable('booking_logs')) {
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->boolean('invoice_status')
|
||||
->default(false)
|
||||
->after('status');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,8 +29,10 @@ class AddInvoiceStatusToBookingLogsTable extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('invoice_status');
|
||||
});
|
||||
if (Schema::hasTable('booking_logs')) {
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('invoice_status');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -13,11 +13,13 @@ class AddIsInvoiceGeneratedToBookingLogsTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->boolean('is_invoice_generated')
|
||||
->default(false)
|
||||
->after('status');
|
||||
});
|
||||
if (Schema::hasTable('booking_logs')) {
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->boolean('is_invoice_generated')
|
||||
->default(false)
|
||||
->after('status');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,8 +29,10 @@ class AddIsInvoiceGeneratedToBookingLogsTable extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('is_invoice_generated');
|
||||
});
|
||||
if (Schema::hasTable('booking_logs')) {
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('is_invoice_generated');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -13,9 +13,11 @@ class RemoveIsInvoiceGeneratedFromBookingLogsTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('is_invoice_generated');
|
||||
});
|
||||
if (Schema::hasTable('booking_logs')) {
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('is_invoice_generated');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25,10 +27,12 @@ class RemoveIsInvoiceGeneratedFromBookingLogsTable extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->boolean('is_invoice_generated')
|
||||
->default(false)
|
||||
->after('status');
|
||||
});
|
||||
if (Schema::hasTable('booking_logs')) {
|
||||
Schema::table('booking_logs', function (Blueprint $table) {
|
||||
$table->boolean('is_invoice_generated')
|
||||
->default(false)
|
||||
->after('status');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('activity_log', function (Blueprint $table) {
|
||||
$table->uuid('batch_uuid')->nullable()->after('properties');
|
||||
$table->string('event')->nullable()->after('subject_type');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('activity_log', function (Blueprint $table) {
|
||||
$table->dropColumn('batch_uuid');
|
||||
$table->dropColumn('event');
|
||||
});
|
||||
}
|
||||
};
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
* Update all roles (id 1 & 2) and all permissions to use 'api' guard_name
|
||||
* instead of 'web', to align with Spatie Laravel Permission v7 strict
|
||||
* guard matching behaviour for SPA/API-based requests.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
DB::table('roles')->where('id', 1)->update(['guard_name' => 'api']);
|
||||
DB::table('roles')->where('id', 2)->update(['guard_name' => 'api']);
|
||||
DB::table('permissions')->where('id', '>', 0)->update(['guard_name' => 'api']);
|
||||
|
||||
// Clear Spatie permission cache so changes take effect immediately
|
||||
app()['cache']->forget('spatie.permission.cache');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('roles')->where('id', 1)->update(['guard_name' => 'web']);
|
||||
DB::table('roles')->where('id', 2)->update(['guard_name' => 'web']);
|
||||
DB::table('permissions')->where('id', '>', 0)->update(['guard_name' => 'web']);
|
||||
|
||||
// Clear Spatie permission cache so rollback takes effect immediately
|
||||
app()['cache']->forget('spatie.permission.cache');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('transactions', function (Blueprint $table) {
|
||||
$table->unsignedTinyInteger('process_status')
|
||||
->nullable()
|
||||
->default(null)
|
||||
->after('status')
|
||||
->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('transactions', function (Blueprint $table) {
|
||||
$table->dropColumn('process_status');
|
||||
});
|
||||
}
|
||||
};
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (!Schema::hasTable('transaction_logs')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('transaction_logs', function (Blueprint $table) {
|
||||
$table->unsignedTinyInteger('process_status')
|
||||
->nullable()
|
||||
->default(null)
|
||||
->after('status')
|
||||
->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
if (!Schema::hasTable('transaction_logs')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('transaction_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('process_status');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -20,61 +20,61 @@ class AdminUserPermissionsTableSeeder extends Seeder
|
||||
|
||||
// admin permissions
|
||||
$permissions = [
|
||||
['name' => 'view document', 'guard_name' => 'web'],
|
||||
['name' => 'add document', 'guard_name' => 'web'],
|
||||
['name' => 'edit document', 'guard_name' => 'web'],
|
||||
['name' => 'delete document', 'guard_name' => 'web'],
|
||||
['name' => 'view document', 'guard_name' => 'api'],
|
||||
['name' => 'add document', 'guard_name' => 'api'],
|
||||
['name' => 'edit document', 'guard_name' => 'api'],
|
||||
['name' => 'delete document', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'view standard_segment', 'guard_name' => 'web'],
|
||||
['name' => 'add standard_segment', 'guard_name' => 'web'],
|
||||
['name' => 'edit standard_segment', 'guard_name' => 'web'],
|
||||
['name' => 'delete standard_segment', 'guard_name' => 'web'],
|
||||
['name' => 'view standard_segment', 'guard_name' => 'api'],
|
||||
['name' => 'add standard_segment', 'guard_name' => 'api'],
|
||||
['name' => 'edit standard_segment', 'guard_name' => 'api'],
|
||||
['name' => 'delete standard_segment', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'view standard_segment_constant', 'guard_name' => 'web'],
|
||||
['name' => 'add standard_segment_constant', 'guard_name' => 'web'],
|
||||
['name' => 'edit standard_segment_constant', 'guard_name' => 'web'],
|
||||
['name' => 'delete standard_segment_constant', 'guard_name' => 'web'],
|
||||
['name' => 'view standard_segment_constant', 'guard_name' => 'api'],
|
||||
['name' => 'add standard_segment_constant', 'guard_name' => 'api'],
|
||||
['name' => 'edit standard_segment_constant', 'guard_name' => 'api'],
|
||||
['name' => 'delete standard_segment_constant', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'view segment', 'guard_name' => 'web'],
|
||||
['name' => 'add segment', 'guard_name' => 'web'],
|
||||
['name' => 'edit segment', 'guard_name' => 'web'],
|
||||
['name' => 'delete segment', 'guard_name' => 'web'],
|
||||
['name' => 'view segment', 'guard_name' => 'api'],
|
||||
['name' => 'add segment', 'guard_name' => 'api'],
|
||||
['name' => 'edit segment', 'guard_name' => 'api'],
|
||||
['name' => 'delete segment', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'view segment_constant', 'guard_name' => 'web'],
|
||||
['name' => 'add segment_constant', 'guard_name' => 'web'],
|
||||
['name' => 'edit segment_constant', 'guard_name' => 'web'],
|
||||
['name' => 'delete segment_constant', 'guard_name' => 'web'],
|
||||
['name' => 'view segment_constant', 'guard_name' => 'api'],
|
||||
['name' => 'add segment_constant', 'guard_name' => 'api'],
|
||||
['name' => 'edit segment_constant', 'guard_name' => 'api'],
|
||||
['name' => 'delete segment_constant', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'view company_bank', 'guard_name' => 'web'],
|
||||
['name' => 'add company_bank', 'guard_name' => 'web'],
|
||||
['name' => 'edit company_bank', 'guard_name' => 'web'],
|
||||
['name' => 'delete company_bank', 'guard_name' => 'web'],
|
||||
['name' => 'view company_bank', 'guard_name' => 'api'],
|
||||
['name' => 'add company_bank', 'guard_name' => 'api'],
|
||||
['name' => 'edit company_bank', 'guard_name' => 'api'],
|
||||
['name' => 'delete company_bank', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'view currency', 'guard_name' => 'web'],
|
||||
['name' => 'add currency', 'guard_name' => 'web'],
|
||||
['name' => 'edit currency', 'guard_name' => 'web'],
|
||||
['name' => 'delete currency', 'guard_name' => 'web'],
|
||||
['name' => 'view currency', 'guard_name' => 'api'],
|
||||
['name' => 'add currency', 'guard_name' => 'api'],
|
||||
['name' => 'edit currency', 'guard_name' => 'api'],
|
||||
['name' => 'delete currency', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'view currency_rate', 'guard_name' => 'web'],
|
||||
['name' => 'add currency_rate', 'guard_name' => 'web'],
|
||||
['name' => 'edit currency_rate', 'guard_name' => 'web'],
|
||||
['name' => 'delete currency_rate', 'guard_name' => 'web'],
|
||||
['name' => 'view currency_rate', 'guard_name' => 'api'],
|
||||
['name' => 'add currency_rate', 'guard_name' => 'api'],
|
||||
['name' => 'edit currency_rate', 'guard_name' => 'api'],
|
||||
['name' => 'delete currency_rate', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'view booking', 'guard_name' => 'web'],
|
||||
['name' => 'add booking', 'guard_name' => 'web'],
|
||||
['name' => 'edit booking', 'guard_name' => 'web'],
|
||||
['name' => 'delete booking', 'guard_name' => 'web'],
|
||||
['name' => 'view booking', 'guard_name' => 'api'],
|
||||
['name' => 'add booking', 'guard_name' => 'api'],
|
||||
['name' => 'edit booking', 'guard_name' => 'api'],
|
||||
['name' => 'delete booking', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'add milestone', 'guard_name' => 'web'],
|
||||
['name' => 'add reward', 'guard_name' => 'web'],
|
||||
['name' => 'edit milestone', 'guard_name' => 'web'],
|
||||
['name' => 'delete milestone', 'guard_name' => 'web'],
|
||||
['name' => 'delete reward', 'guard_name' => 'web'],
|
||||
['name' => 'add milestone', 'guard_name' => 'api'],
|
||||
['name' => 'add reward', 'guard_name' => 'api'],
|
||||
['name' => 'edit milestone', 'guard_name' => 'api'],
|
||||
['name' => 'delete milestone', 'guard_name' => 'api'],
|
||||
['name' => 'delete reward', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'add voucher', 'guard_name' => 'web'],
|
||||
['name' => 'list voucher campaigns', 'guard_name' => 'web'],
|
||||
['name' => 'add voucher', 'guard_name' => 'api'],
|
||||
['name' => 'list voucher campaigns', 'guard_name' => 'api'],
|
||||
|
||||
['name' => 'update bank_metadata', 'guard_name' => 'web'],
|
||||
['name' => 'update bank_metadata', 'guard_name' => 'api'],
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission){
|
||||
@@ -87,7 +87,7 @@ class AdminUserPermissionsTableSeeder extends Seeder
|
||||
['name' => 'Shadow Admin'],
|
||||
[
|
||||
'name' => 'Shadow Admin',
|
||||
'guard_name' => 'web',
|
||||
'guard_name' => 'api',
|
||||
'type' => 1,
|
||||
]
|
||||
);
|
||||
@@ -108,7 +108,7 @@ class AdminUserPermissionsTableSeeder extends Seeder
|
||||
['name' => 'Ultimate Admin'],
|
||||
[
|
||||
'name' => 'Ultimate Admin',
|
||||
'guard_name' => 'web',
|
||||
'guard_name' => 'api',
|
||||
'type' => 1,
|
||||
]
|
||||
);
|
||||
@@ -125,7 +125,7 @@ class AdminUserPermissionsTableSeeder extends Seeder
|
||||
['name' => 'Admin'],
|
||||
[
|
||||
'name' => 'Admin',
|
||||
'guard_name' => 'web',
|
||||
'guard_name' => 'api',
|
||||
'type' => 1,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -683,7 +683,7 @@ class DummyDataSeeder extends Seeder
|
||||
'generateEInvoice' => false,
|
||||
'generateEInvoiceWithNormalInvoiceTemplate' => false,
|
||||
'generateEInvoiceRefund' => false,
|
||||
'bookingOriginalStatus' => ApprovalStatus::COMPLETED
|
||||
'bookingOriginalStatus' => ApprovalStatus::COMPLETED //cief todo: 151
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user