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

This commit is contained in:
Dillon Ngo
2024-10-16 15:49:55 +08:00
17 changed files with 335 additions and 48 deletions
@@ -0,0 +1,49 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\ListsTransactions;
use App\Http\Resources\TransactionUrgentResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListUrgentTransactionsLogic extends AbstractControllerLogic
{
/**
* ListUrgentTransactionsLogic constructor.
* @param ListsTransactions $listsTransactions
*/
public function __construct(ListsTransactions $listsTransactions)
{
$this->listsTransactions = $listsTransactions;
}
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Transactions Urgent',
'message' => 'You have successfully retrieved a list of transactions'
];
}
/** @var ListsTransactions */
private $listsTransactions;
public function logic(Request $request) : JsonResponse
{
$query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($request->input('filters')));
return $this->collectionResponse(TransactionUrgentResource::collection($query));
}
}
@@ -8,6 +8,7 @@ use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Models\Document;
use Illuminate\Support\Facades\Log;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use Webklex\PDFMerger\Facades\PDFMergerFacade as PDFMerger;
use Illuminate\Support\Facades\Storage;
@@ -50,22 +51,44 @@ class CreateInvoiceDocumentProcessor
$oMerger = PDFMerger::init();
$saveDirectory = storage_path('app/documents');
if (!file_exists($saveDirectory)) {
mkdir($saveDirectory, 0755, true);
}
$order_pdf->save(storage_path('app/documents/temp.pdf'));
$oMerger->addPDF(storage_path('app/documents/temp.pdf'), 'all');
$filesystemDriver = Storage::getDefaultDriver();
foreach ($purchaseOrderDocuments as $document){
$localFilePath = storage_path('app/documents/' . $document->files()->first()->file->file_info->original->file);
$oMerger->addPDF($localFilePath, 'all');
$currentFile = $document->files()->first()->file->file_info->original->file;
if($filesystemDriver === 's3'){
$filePathForS3 = 'documents/'.$document->files()->first()->file->file_info->original->file;
Storage::disk('s3')->put($filePathForS3, file_get_contents($localFilePath));
Log::info('CreateInvoiceDocumentProcessor 1: ' . $currentFile);
$fileContent = Storage::disk('s3')->get($currentFile);
$filepath = storage_path('app/documents/' . $currentFile);
$directoryPath = dirname($filepath);
if (!file_exists($directoryPath)) {
mkdir($directoryPath, 0755, true);
}
file_put_contents($filepath, $fileContent);
}
$localFilePath = storage_path('app/documents/' . $currentFile);
$oMerger->addPDF($localFilePath, 'all');
}
$oMerger->merge();
$order_pdf = $oMerger;
if($filesystemDriver === 's3'){
$finalTempPdfPath = storage_path('app/documents/temp.pdf');
$filePathForS3 = 'temp/temp.pdf';
$fileContent = file_get_contents($finalTempPdfPath);
Log::info('CreateInvoiceDocumentProcessor 2 filePathForS3: ' . $filePathForS3);
Storage::disk('s3')->put($filePathForS3, $fileContent);
}
}
$document_object = new DocumentObject(
+12 -14
View File
@@ -50,23 +50,21 @@ class Kernel extends ConsoleKernel
->withoutOverlapping();
if(env('APP_ENV') === 'production'){
//cief todo: disable commands to avoid unintentional interfering with production starts
// $schedule->command('email-do-to-vt-command')
// ->dailyAt('10:00')
// ->withoutOverlapping();
$schedule->command('email-do-to-vt-command')
->dailyAt('10:00')
->withoutOverlapping();
// $schedule->command('seasonal-segmant-company-remove-command')
// ->dailyAt('01:00')
// ->withoutOverlapping();
$schedule->command('seasonal-segmant-company-remove-command')
->dailyAt('01:00')
->withoutOverlapping();
// $schedule->command('delete-bulk-download-files-command')
// ->hourly()
// ->withoutOverlapping();
$schedule->command('delete-bulk-download-files-command')
->hourly()
->withoutOverlapping();
// $schedule->command('booking-expired-command')
// ->dailyAt('02:00')
// ->withoutOverlapping();
//cief todo: disable commands to avoid unintentional interfering with production
$schedule->command('booking-expired-command')
->dailyAt('02:00')
->withoutOverlapping();
// DISABLED BY DEFAULT
// $schedule->command('purchase-order-autofill-command')
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Transactions;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\ListUrgentTransactionsLogic;
class ListUrgentTransactionsController
{
/**
* @param Request $request
* @param ListTransactionsLogic $logic
* @return JsonResponse
*/
public function list(Request $request, ListUrgentTransactionsLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,73 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class BookingForTransactionUrgentResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function toArray($request)
{
return [
'id' => $this->id,
'company_reference' => $this->company->reference, //new CompanyResource($this->company)
'bank' => new BankResource($this->bank),
'service' => new ServiceTypeResource($this->service),
'marking' => $this->marking,
// 'amount' => $this->fix_amount,
// 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)),
// 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
// // 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) + floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
// 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)),
// 'fixed_currency' => new CurrencyResource($this->fixedCurrency),
// 'convertible_currency' => new CurrencyResource($this->convertibleCurrency),
// 'conversion_currency' => new CurrencyResource($this->conversionCurrency),
// 'documents' => [
// 'purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()),
// 'delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()),
// 'invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->first()),
// 'supplier_delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()),
// 'proforma_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()),
// 'ecommerce_purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first()),
// ],
// 'order_reference_no' => $this->modelAttributes()->where('name', BookingAttributeNames::ORDER_REFERENCE_NO)->get()->map(function ($attr) {
// return [
// 'id' => $attr->id,
// 'value' => $attr->value
// ];
// }),
// 'status' => $this->status,
// 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'),
// 'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
// $this->mergeWhen($this->relationLoaded('transactions'), [
// 'purchase_order' => new TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()),
// 'payment_attempts' => TransactionResource::collection(
// $this->transactions()
// ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)
// ->whereDate('expires_on', '>=', Carbon::now())
// ->get()
// ),
// // 'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()),
// 'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::EXPIRED)->get()),
// 'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){
// $query->where(function($query){
// $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED, ApprovalStatus::REFUNDED]);
// })->orWhere(function($query){
// $query->where(function($query){
// $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]);
// })->orWhere(function($query){
// $query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
// });
// });
// })->latest()->get())
// ])
];
}
}
@@ -0,0 +1,29 @@
<?php
namespace App\Http\Resources;
use App\Models\Booking;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
class DocumentForTransactionUrgentResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
// 'reference' => $this->reference,
// 'status' => (int) $this->status,
// 'document_type' => $this->document_type,
// 'owner' => $this->relationLoaded('owner') ? ($this->owner instanceof Booking ? new BookingResource($this->owner) : new CompanyResource($this->owner)) : null,
// 'files' => FileResource::collection($this->files),
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A')
];
}
}
@@ -0,0 +1,71 @@
<?php
namespace App\Http\Resources;
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
class TransactionUrgentResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$booking = null; //cief todo: 66
$bank = null;
//Check if Transaction of type PAYMENT has an override for recipient bank - starts
if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])){
$booking = $this->owner->owner;
$bank = $this->owner->bank ?? $booking->bank;
}
else{
$booking = $this->owner;
$bank = $this->bank ?? $booking->bank;
}
//Check if Transaction of type PAYMENT has an override for recipient bank - ends
$days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1);
return [
'id' => $this->id,
'booking' => new BookingForTransactionUrgentResource($booking),
// 'type' => (int) $this->type,
// 'bill_no' => $this->bill_no,
// 'payment_reference' => $this->payment_reference,
// 'payment_method' => (float) $this->payment_method,
'recipient_bank_account' => new BankResource($bank),
// 'issuer_name' => $this->issuerCompany->name,
// 'issuer_id' => $this->issuerCompany->id,
// 'amount' => (double) ($this->type === TransactionType::SUPPLIER_REFUND ? $this->amount - $this->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->sum('amount') : $this->amount),
'original_amount' => (double) ($this->type === TransactionType::SUPPLIER_REFUND ? $this->original_amount - $this->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->sum('original_amount') : $this->original_amount),
// 'currency' => new CurrencyResource($this->currency),
// 'original_currency' => new CurrencyResource($this->original_currency),
// 'service_charge' => (double) $this->service_charge,
// 'tax' => (double) $this->tax,
// 'currency_rate' => (double) $this->currency_rate,
// 'status' => (int) $this->status,
//'details' => TransactionDetailResource::collection($this->transactionDetails),
'documents' => new DocumentForTransactionUrgentResource($this->documents()->first()),
//'transaction_bill' => new TransactionResource($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first())),
//'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())),
//'refunded_amount' => $this->booking ? floatval((App()->make(CalculatesBookingRefundAmount::class))->calculateRefundAmount($this->resource, $this->booking->fix_currency_id)) : null,
// 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'),
'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'),
// 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
'interval' => [
'value' => $days->gt(Carbon::now()) ? '+' : '-',
'duration' => $days->diff(Carbon::now())->format('%d'),
],
//'remarks' => RemarkResource::collection($this->remarks),
//'redemption' => new VoucherRedemptionResource($this->voucherRedemption),
// '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
];
}
}
@@ -26,16 +26,26 @@
<i class="fa fa-font"></i>
</button>
</a>
<a :href="route('group.excel', item.id)" target="_blank" v-tooltip:top="'Export in Excel'" class="m-l-5">
<!-- <a :href="route('group.excel', item.id)" target="_blank" v-tooltip:top="'Export in Excel'" class="m-l-5">
<button class="btn btn-xs b-rad-none">
<i class="fa fa-file-excel-o"></i>
</button>
</a>
<a :href="route('group.invoice', item.id)" target="_blank" v-tooltip:top="'Export Invoice PDF'" class="m-l-5">
</a> -->
<open-link-in-new-tab-component custom-class="m-l-5" :url="route('group.excel', item.id)" tooltip="Export in Excel" :show-spinner="false">
<button class="btn btn-xs b-rad-none">
<i class="fa fa-file-excel-o"></i>
</button>
</open-link-in-new-tab-component>
<!-- <a :href="route('group.invoice', item.id)" target="_blank" v-tooltip:top="'Export Invoice PDF'" class="m-l-5">
<button class="btn btn-xs b-rad-none">
<i class="fa fa-list-alt"></i>
</button>
</a>
</a> -->
<open-link-in-new-tab-component custom-class="m-l-5" :url="route('group.invoice', item.id)" tooltip="Export Invoice PDF" :show-spinner="false">
<button class="btn btn-xs b-rad-none">
<i class="fa fa-list-alt"></i>
</button>
</open-link-in-new-tab-component>
</div>
</div>
</div>
@@ -18,7 +18,7 @@
<p><span class="text-primary">{{item.recipient_bank_account.type === 3 ? item.recipient_bank_account.account_no : item.recipient_bank_account.account_no.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim()}}</span></p>
</td>
<td class="v-align-middle">
<p>{{item.booking.company.reference}}</p>
<p>{{item.booking.company_reference}}</p>
</td>
<td class="v-align-middle">
<p>{{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</p>
@@ -48,7 +48,7 @@
},
methods: {
fetchList(Page = 1){
this.submit(route('api.transaction.list') + '?page='+ Page +'&filters=' + JSON.stringify({status: 2, type: 1, owner_type: 'App\\Models\\Booking', per_page: 50, order_by: {
this.submit(route('api.transaction.list.urgent') + '?page='+ Page +'&filters=' + JSON.stringify({status: 2, type: 1, owner_type: 'App\\Models\\Booking', per_page: 50, order_by: {
column: 'created_at',
DESC: true
}}), 'get', 'urgentListSection', false, true)
@@ -59,4 +59,4 @@
}
}
}
</script>
</script>
@@ -2,9 +2,10 @@
<span>
<a
:class="[customClass, { 'link-disabled': isDownloading }]"
@click.prevent="handleClick">
@click.prevent="handleClick"
v-tooltip:top="tooltip ? tooltip : ''">
<slot></slot>
<span v-if="isDownloading" class="spinner"></span>
<span v-if="isDownloading && showSpinner" class="spinner"></span>
</a>
</span>
</template>
@@ -23,7 +24,15 @@
customClass:{
type: String,
default: ''
}
},
tooltip:{
type: String,
default: ''
},
showSpinner: {
type: Boolean,
default: true
},
},
data() {
return {
@@ -97,11 +97,16 @@
vm.isLoading = true;
const pdfIconUrl = "https://assets.izyim.com/public/images/icons/pdf.png";
const xlsIconUrl = "https://assets.izyim.com/public/images/icons/xlsx.png";
if(file.name.split('.').pop() === 'pdf'){
$(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", asset("images/icons/pdf.png"));
// $(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", asset("images/icons/pdf.png"));
$(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", pdfIconUrl);
}
if(file.name.split('.').pop().indexOf("xls") !== -1){
$(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", asset("images/icons/xlsx.png"));
// $(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", asset("images/icons/xlsx.png"));
$(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", xlsIconUrl);
}
Promise.all(dropzone.files.map(function(file){
+1 -1
View File
@@ -12,7 +12,7 @@ export default {
let decodedParams = fullyDecodeURI(encodedParams);
const queryParams = encodeURIComponent(decodedParams);
queryDomain = encodeUrlWithoutQueryParameter(queryDomain)
console.log("queryDomain: " + queryDomain);
encodedParams = queryParams.toString();
let filteredEncodedParams = encodedParams.replace(/%3D/g,'=');
filteredEncodedParams = filteredEncodedParams.replace(/%26/g,'&');
+1 -1
View File
@@ -8,7 +8,7 @@ export default {
let decodedParams = fullyDecodeURI(encodedParams);
const queryParams = encodeURIComponent(decodedParams);
queryDomain = encodeUrlWithoutQueryParameter(queryDomain)
console.log("queryDomain: " + queryDomain);
encodedParams = queryParams.toString();
let filteredEncodedParams = encodedParams.replace(/%3D/g,'=');
filteredEncodedParams = filteredEncodedParams.replace(/%26/g,'&');
+1
View File
@@ -6,6 +6,7 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' =>
Route::get('/list', 'ListTransactionsController@list')->name('list');
Route::get('/list/job', 'ListTransactionsJobController@list')->name('list.job');
Route::get('/list/urgent', 'ListUrgentTransactionsController@list')->name('list.urgent');
Route::delete('/suspend/{id}', 'SuspendTransactionController@suspend')->name('suspend');
route::post('/supplier/{id}/bill/create', 'CreateSupplierTransactionController@create')->name('supplier.create');
+11 -15
View File
@@ -36,7 +36,7 @@ use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionWithInvo
use App\Classes\Modules\Transactions\Services\DeletesTransaction;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Classes\General\AWSS3Helper;
/*
|--------------------------------------------------------------------------
@@ -621,7 +621,15 @@ Route::get('/group/invoice/{id}', function ($id) {
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
return $dompdf->stream("invoice_pdf_{$supplier->name}.pdf");
$exportFileName = "invoice_pdf_{$supplier->name}.pdf";
$filesystemDriver = Storage::getDefaultDriver();
if($filesystemDriver === 's3'){
$pdfContent = $dompdf->output();
return response([ 'src' => AWSS3Helper::S3PDF($exportFileName, $pdfContent) ]);
}
else{
return $dompdf->stream($exportFileName);
}
})->name('group.invoice');
Route::get('/wallet/audit', function (Request $request) {
@@ -1233,19 +1241,7 @@ Route::get('check-duplicate-refunds', function () {
echo '</table>';
});
//Laravel Vapor - Starts
// Route::get('/aws-image-upload', 'AWS\AWSImageUploadController@imageUpload')->name('aws.image.upload');
// Route::post('/aws-image-upload', 'AWS\AWSImageUploadController@imageUploadPost')->name('aws.image.upload.post');
// Route::get('/aws-image/{filename}', 'AWS\AWSImageUploadController@displayImage')->name('aws.image.displayImage');
// Route::get('/token', function (Request $request) {
// $token = $request->session()->token();
// echo $token;
// $token = csrf_token();
// echo $token;
// });
Route::get('/downloads', function () {
return view('pages.downloads.index');
})->name('admin.download');
//Laravel Vapor - Ends
+3 -1
View File
@@ -3,7 +3,9 @@ name: exchange
separate-vendor: true
environments:
production:
domain: production.exchange.izyim.com
domain:
- production.exchange.izyim.com
- exchange.cief-malaysia.com
memory: 1024
cli-memory: 512
queues: