Laravel Vapor - Version 2 of Commands for 3 files + Resolved 3 TODOs

This commit is contained in:
Dillon Ngo
2024-03-24 18:20:24 +08:00
parent 4ec90b68da
commit a200f7083b
9 changed files with 420 additions and 7 deletions
@@ -0,0 +1,89 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\Booking;
use App\Models\Transaction;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor;
use App\Classes\Modules\Transactions\Services\GeneratesPurchaseOrderProducts;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class AutoFillPurchaseOrderV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Auto fill up the purchase order for booking that have payment.');
$start = new Carbon();
// 5. If purchase order not fill up in 2 month, auto fill up it
$bookings = Booking::where('status', ApprovalStatus::APPROVED)
->where('created_at', '<', now()->subDays(60)->endOfDay())
->whereHas('transactions', function($transaction) {
return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})
->whereDoesntHave('transactions', function($transaction){
$transaction->where('type', TransactionType::PURCHASE_ORDER);
$transaction->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]);
})->get();
Log::info('Bookings count: '.count($bookings));
foreach ($bookings as $booking) {
$po = Transaction::where('type', TransactionType::PURCHASE_ORDER)
->where('status', ApprovalStatus::APPROVED)->where('issuer', $booking->company_id)
->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first();
if (!$po) {
$po = Transaction::where('type', TransactionType::PURCHASE_ORDER)
->where('status', ApprovalStatus::APPROVED)->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first();
}
$products = (App()->make(GeneratesPurchaseOrderProducts::class))->execute($po, $booking->fix_amount);
$deference = $booking->fix_amount - $products->sum('total');
if($deference > -150 && $deference < 150 && $deference != 0) {
$products->push([
'description' => $deference < 0 ? 'Discount':'Shipping Fee',
'quantity' => 1,
'stockCode' => '',
'total' => $deference,
'unit_price' => $deference
]);
}
$billNumber = (App()->make(GeneratesTransactionBillNumber::class))->execute('XPO-');
Log::info('Single booking billNumber: '.$billNumber);
$total = $products->sum('total');
$object = new TransactionObject($billNumber, TransactionType::PURCHASE_ORDER, $booking->company->id, 1,
1, PaymentMethodType::CASH,
$total, $total, $booking->fix_currency_id, $booking->fix_currency_id,
1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $products->toArray());
(App()->make(CreatePurchaseOrderTransactionProcessor::class))->execute($booking, $object);
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Auto fill up the purchase order for booking that have payment. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,81 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus;
use Illuminate\Support\Facades\Log;
class ExpiredBookingV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Expiring booking that do not have further action by user.');
$start = new Carbon();
// 1. Cancel booking without payment & purchase order (1 month)
$bookings = Booking::where('status', ApprovalStatus::APPROVED)
->where('created_at', '<', now()->subDays(30)->endOfDay())
->where(function ($query) {
$query->whereDoesntHave('transactions')
->orWhereDoesntHave('transactions', function($transaction) {
return $transaction->where('type', TransactionType::PURCHASE_ORDER)->orWhere(function ($q) {
$q->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
});
});
})->get();
foreach ($bookings as $booking) {
(App()->make(UpdatesBookingStatus::class))->execute($booking, ApprovalStatus::EXPIRED);
Log::info(Carbon::now() . " : Expired Booking without payment & purchase order, booking id: " . $booking->id);
$transactions = $booking->transactions;
foreach ($transactions as $transaction) {
$prevStatus = $transaction->status;
$transaction->status = ApprovalStatus::EXPIRED;
$transaction->save();
Log::info(Carbon::now() . " : Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}");
}
}
// 2. Cancel booking without payment but with purchase order (2 month)
$bookings = Booking::where('status', ApprovalStatus::APPROVED)
->where('created_at', '<', now()->subDays(60)->endOfDay())
->where(function ($query) {
$query->whereDoesntHave('transactions', function($transaction) {
return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})->whereHas('transactions', function($transaction) {
return $transaction->where('type', TransactionType::PURCHASE_ORDER);
});
})->get();
foreach ($bookings as $booking) {
(App()->make(UpdatesBookingStatus::class))->execute($booking, ApprovalStatus::EXPIRED);
Log::info(Carbon::now() . " : Expired Booking without payment but with purchase order, booking id: " . $booking->id);
$transactions = $booking->transactions;
foreach ($transactions as $transaction) {
$prevStatus = $transaction->status;
$transaction->status = ApprovalStatus::EXPIRED;
$transaction->save();
Log::info(Carbon::now() . " : Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}");
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Expiring booking that do not have further action by user. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,137 @@
<?php
namespace App\Classes\Jobs\Commands\V2;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Models\Transaction;
use Illuminate\Support\Facades\Log;
class ExpiredRefundedBookingV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Log::info(Carbon::now() . ': Start job - Expiring refunded booking.');
$start = new Carbon();
// 3. Cancel fully refunded payment & cancel booking
$transactions = Transaction::where('type', TransactionType::CREDIT_NOTE)->where('payment_reference', 'LIKE', "%refund%")->get();
foreach ($transactions as $transaction) {
// get the booking marking
$payment_reference = explode(" ", trim($transaction->payment_reference));
// $marking = substr($transaction->payment_reference, -5);
$marking = trim(end($payment_reference));
if (!preg_match('/^[0-9]+$/', $marking)) {
$payment_reference = explode(".", trim($transaction->payment_reference));
$marking = trim(end($payment_reference));
}
// for a special payment reference on transaction id: 140231
if (!preg_match('/^[0-9]+$/', $marking)) {
$payment_reference = explode("No", trim($transaction->payment_reference));
$marking = end($payment_reference);
}
// for a special payment reference on transaction id: 152013
if (!preg_match('/^[0-9]+$/', $marking)) {
$payment_reference = explode(" ", trim($transaction->payment_reference));
$marking = end($payment_reference);
$marking = prev($payment_reference);
}
if (preg_match('/^[0-9]+$/', $marking)) {
$booking = Booking::where('marking', $marking)->first();
if ($booking) {
$bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first();
if (!$bookingPayment) {
$bookingPaymentCount = $booking->transactions()->payments()->count();
if ($bookingPaymentCount > 1) {
Log::info("Credit note transaction id: {$transaction->id}, there are {$bookingPaymentCount} payment for the booking.");
foreach ($booking->transactions()->payments()->get() as $bp) {
if ($transaction->amount - $bp->amount < 0.01) {
$bookingPayment = $bp;
break;
}
}
}
if (!$bookingPayment) {
$bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED, ApprovalStatus::REJECTED])->orderBy('id', 'DESC')->first();
}
$status = ApprovalStatus::APPROVAL_STATUS_ID[$bookingPayment->status];
Log::info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}");
}
$bookingPaymentAmount = $bookingPayment->amount;
// check if the booking is fully refund
$amountDifference = bcsub($transaction->amount, $bookingPaymentAmount, 7);
if (abs($amountDifference) < 0.01) {
// rejecting booking payment transaction
// $bookingPayment->status = ApprovalStatus::REJECTED;
// $bookingPayment->save();
//expired booking
// $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED);
Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}");
// Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}");
// Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}");
} else {
Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}");
}
$refund = $bookingPayment->transactions()->refunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first();
$bookingInWhiteForm = $bookingPayment->transactions()->bills()->first();
if ($refund) {
Log::info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction");
}
if ($bookingInWhiteForm) {
Log::info("Credit note transaction id: {$transaction->id}, booking is in white form");
}
if (!$refund && !$bookingInWhiteForm) {
$billNumber = (App()->make(GeneratesTransactionBillNumber::class))->execute('RFD-');
$object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id,
1, PaymentMethodType::CASH,
$transaction->amount, $transaction->amount * $bookingPayment->currency_rate, 1,
$bookingPayment->original_currency_id, $bookingPayment->currency_rate,
0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no);
$transaction =(App()->make(CreatesTransaction::class))->execute($bookingPayment, $object);
}
} else {
Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}");
}
} else {
Log::info("Credit note transaction id: {$transaction->id} does not have booking marking, the payment reference is: {$transaction->payment_reference}");
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Expiring refunded booking. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,34 @@
<?php
namespace App\Console\Commands\V2;
use App\Classes\Jobs\Commands\V2\AutoFillPurchaseOrderV2CommandJob;
use Illuminate\Console\Command;
class AutoFillPurchaseOrderV2Command extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'purchase-order-autofill-command';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Auto fill up the purchase order for booking that have payment';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
AutoFillPurchaseOrderV2CommandJob::dispatch();
}
}
@@ -0,0 +1,34 @@
<?php
namespace App\Console\Commands\V2;
use App\Classes\Jobs\Commands\V2\ExpiredBookingV2CommandJob;
use Illuminate\Console\Command;
class ExpiredBookingV2Command extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'booking-expired-command';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Expiring booking that do not have further action by user';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ExpiredBookingV2CommandJob::dispatch();
}
}
@@ -0,0 +1,34 @@
<?php
namespace App\Console\Commands\V2;
use App\Classes\Jobs\Commands\V2\ExpiredRefundedBookingV2CommandJob;
use Illuminate\Console\Command;
class ExpiredRefundedBookingV2Command extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'refunded-booking-expired-command';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Expiring refunded booking';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ExpiredRefundedBookingV2CommandJob::dispatch();
}
}
+8 -2
View File
@@ -52,6 +52,14 @@ class Kernel extends ConsoleKernel
$schedule->command('new-user-registration-expire-check-command')
->dailyAt('23:55')
->withoutOverlapping();
$schedule->command('booking-expired-command')
->dailyAt('02:00')
->withoutOverlapping();
// $schedule->command('purchase-order-autofill-command')
// ->dailyAt('03:00')
// ->withoutOverlapping();
}
//Commands Version 1: Before Laravel Vapor/AWS
else{
@@ -68,13 +76,11 @@ class Kernel extends ConsoleKernel
->appendOutputTo(storage_path().'/logs/delete-bulk-download-files.log')
->withoutOverlapping();
//cief todo: command version 2
$schedule->command('booking:expired')
->dailyAt('02:00')
->appendOutputTo(storage_path().'/logs/expire-booking.log')
->withoutOverlapping();
//cief todo: command version 2
// $schedule->command('purchaseOrder:autoFill')
// ->dailyAt('03:00')
// ->withoutOverlapping();
+2 -2
View File
@@ -1,8 +1,8 @@
export default {
actions: {
crudRequest({getters, dispatch}, {endpoint, method, parameters}){
console.log(endpoint);
console.log(window.LARAVEL_VAPOR_ENABLED);
// console.log(endpoint);
// console.log(window.LARAVEL_VAPOR_ENABLED);
return dispatch('ensureReCaptchaIsSet').then(function () {
let combinedAbsoluteUrl = endpoint;
if(window.LARAVEL_VAPOR_ENABLED){
+1 -3
View File
@@ -60,15 +60,13 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function
require __DIR__ . '/wallet.php';
require __DIR__ . '/voucher.php';
require __DIR__ . '/accounting.php';
require __DIR__ . '/reward.php';
require __DIR__ . '/milestone.php';
// require __DIR__ . '/accounting.php'; //cief todo: To check if this is needed
require __DIR__ . '/job.php';
// require __DIR__ . '/rate.php';