Merge branch 'dillon/90-e-invoice-shipping-portal-e-2' into vapor/staging

This commit is contained in:
Dillon Ngo
2025-08-09 22:36:07 +08:00
9 changed files with 114 additions and 23 deletions
@@ -28,6 +28,40 @@ class PackingListLimitOneByTypeOrderedByInvoiceDate implements Filter
SELECT id FROM transactions WHERE owner_id = packing_lists.id AND type = 16 LIMIT 1
))');
})->orderBy('transactions.updated_at', 'DESC');
}
//Original with problem
// return $builder->select('packing_lists.*')->join('transactions', function($join){
// $join->on('transactions.owner_id', '=', 'packing_lists.id');
// $join->where('transactions.owner_type', '=', PackingList::class);
// $join->where('transactions.status', '=', ApprovalStatus::APPROVED);
// $join->whereNull('transactions.deleted_at');
// $join->whereRaw('(transactions.type <> 16 OR transactions.id = (
// SELECT id FROM transactions WHERE owner_id = packing_lists.id AND type = 16 LIMIT 1
// ))');
// })->orderBy('transactions.updated_at', 'DESC');
//Attempt 1
// return $builder->with(['transactions' => function ($query) {
// $query->where('status', ApprovalStatus::APPROVED)
// ->whereNull('deleted_at')
// ->whereRaw('(
// transactions.type <> 16 OR transactions.id = (
// SELECT id FROM transactions AS t2
// WHERE t2.owner_id = transactions.owner_id
// AND t2.owner_type = ?
// AND t2.type = 16
// LIMIT 1
// )
// )', [PackingList::class])
// ->orderBy('updated_at', 'DESC');
// }]);
//Attempt 2
// return $builder->with(['transactions' => function ($query) {
// $query->where('status', ApprovalStatus::APPROVED)
// ->where('type', '<>', 16 )
// ->whereNull('deleted_at')
// ->orderBy('updated_at', 'DESC');
// }]);
}
}
@@ -23,6 +23,7 @@ class PackingListOrderedByInvoiceDate implements Filter
$join->on('transactions.owner_id', '=', 'packing_lists.id');
$join->where('transactions.owner_type', '=', PackingList::class);
$join->where('transactions.status', '=', ApprovalStatus::APPROVED);
$join->whereNull('transactions.deleted_at');
})->orderBy('transactions.updated_at', 'DESC');
}
@@ -0,0 +1,44 @@
<?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\Modules\Orders\Services\ListsOrders;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Classes\ValueObjects\Constants\OrderType;
use Illuminate\Support\Facades\Log;
class CheckStorageInvoicesSingleOrderV2CommandJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $order;
public function __construct($order)
{
$this->order = $order;
}
public function handle()
{
Log::info(Carbon::now() . ': Start job - Check single order for storage invoice.');
$start = new Carbon();
try{
Log::info("Processing Order - ID: {$this->order->id}, Reference: {$this->order->reference}");
(App()->make(CheckStorageInvoiceTransactionProcessor::class))->executeOrder($this->order);
}
catch(\Exception $ex){
Log::info('Exception '.$ex->getMessage());
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
Log::info(Carbon::now() . ': End job - Check single order for storage invoice. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -55,9 +55,6 @@ class ListPackingListsLogic extends AbstractControllerLogic
$query = $this->listsPackingLists->execute($this->listsPackingLists->deserializeFilters($request->input('filters')));
$data = json_encode($request->input('storages'));
Log::info("ListPackingListsLogic storages A");
// if($request->input('storages')){
// Log::info("ListPackingListsLogic storages B");
// foreach ($query->items() as $item) {
@@ -67,6 +64,8 @@ class ListPackingListsLogic extends AbstractControllerLogic
// }
$filters = json_decode($request->input('filters'), true);
Log::info('ListPackingListsLogic storages A with Filters:' . json_encode($filters));
$useNew = false;
foreach ($query->items() as $item) {
//from middleware
@@ -2,6 +2,7 @@
namespace App\Http\Middleware;
use App\Classes\Jobs\Commands\V2\CheckStorageInvoicesSingleOrderV2CommandJob;
use Closure;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Classes\Modules\PackingLists\Services\ListsPackingLists;
@@ -47,15 +48,25 @@ class CheckForStorageInvoiceByPackingLists
// }
if(isset($filters['check_for_storage_invoice'])){
unset($filters['order_by']);
$packinglists = $this->listsPackingLists->execute($filters);
// unset($filters['order_by']); //cief todo: 90 - DEBUG, original
// $packinglists = $this->listsPackingLists->execute($filters); //cief todo: 90 - DEBUG, original
$packinglists = $this->listsPackingLists->execute($this->listsPackingLists->deserializeFilters($request->input('filters'))); //cief todo: 90 - DEBUG
Log::info('CheckForStorageInvoiceByPackingLists $packinglists ' . count($packinglists));
Log::info('CheckForStorageInvoiceByPackingLists $packinglists ' . json_encode($packinglists)); //cief todo: 90 - DEBUG
foreach($packinglists as $packingList){
if($packingList){
$order = $packingList->owner()->first();
if($order instanceof Order){
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
if($storages){
$results = array_merge($results, $storages);
if(isset($filters['check_for_storage_invoice_asynchronously'])){
Log::info("check_for_storage_invoice_asynchronously Order - ID: {$order->id}, Reference: {$order->reference}");
CheckStorageInvoicesSingleOrderV2CommandJob::dispatch($order);
}
else{
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
if($storages){
$results = array_merge($results, $storages);
}
}
}
}
@@ -16,14 +16,14 @@
</div>
<div class="col">
<p class="no-margin fs-10 all-caps">Container</p>
<div v-if="item.packages[0].container"> {{item.packages[0].container.container_reference}}</div>
<div v-if="item.packages[0] && item.packages[0].container"> {{item.packages[0].container.container_reference}}</div>
<div v-else-if="item.container"> {{item.container.container_reference}}</div>
</div>
<div class="col">
<p class="no-margin fs-10 all-caps">Invoice Date</p>
<div v-if="singleInvoice">({{ singleInvoice.bill_no }})</div>
<div v-if="!singleInvoice">n/a</div>
<div v-if="singleInvoice"> {{ singleInvoice.updated_at }}</div>
<div v-if="singleInvoice"> {{ singleInvoice.created_at }}</div>
</div>
<div class="col">
<div v-if="item.order">
@@ -75,9 +75,9 @@
</div>
<div class="row">
<div class="col">
<div class="btn bg-grey no-border" @click="expanded = !expanded" v-if="['Pending Approval', 'Pending Payment'].includes(invoice_status)">
<!-- <div class="btn bg-grey no-border" @click="expanded = !expanded" v-if="['Pending Approval', 'Pending Payment'].includes(invoice_status)">
<i class="fa" :class="{'fa-angle-down': !expanded, 'fa-angle-up': expanded}" ></i>
</div>
</div> -->
<div class="btn bg-grey no-border muted requestModal" v-if="singleInvoice && invoice_status == 'Pending Approval'" data-type="confirmInvoice">
<i class="fa fa-check fs-12"></i>
</div>
@@ -96,7 +96,7 @@
</div>
</div>
</div>
<div class="row b-t b-grey p-t-10 m-l-5 m-r-5" v-show="expanded" v-if="invoice_status == 'Pending Payment'">
<!-- <div class="row b-t b-grey p-t-10 m-l-5 m-r-5" v-show="expanded" v-if="invoice_status == 'Pending Payment'">
<div class="col-12 col-md-7 padding-20">
<div class="row bg-master-lightest h-100">
<div class="col">
@@ -233,7 +233,7 @@
</div>
</div>
</div>
</div>
</div> -->
</div>
</div>
</template>
@@ -75,9 +75,9 @@
</div>
<div class="row">
<div class="col">
<div class="btn bg-grey no-border" @click="expanded = !expanded" v-if="['Pending Approval', 'Pending Payment'].includes(invoice_status)">
<!-- <div class="btn bg-grey no-border" @click="expanded = !expanded" v-if="['Pending Approval', 'Pending Payment'].includes(invoice_status)">
<i class="fa" :class="{'fa-angle-down': !expanded, 'fa-angle-up': expanded}" ></i>
</div>
</div> -->
<div v-if="!item.shipping_transaction">
<div v-if="item.order">
<div v-if="!item.order.company_module.billingAddress">
@@ -196,7 +196,7 @@
</div>
</div>
</div>
<div class="row b-t b-grey p-t-10 m-l-5 m-r-5" v-show="expanded" v-if="item.shipping_transaction && invoice_status == 'Pending Payment'">
<!-- <div class="row b-t b-grey p-t-10 m-l-5 m-r-5 hide" v-show="expanded" v-if="item.shipping_transaction && invoice_status == 'Pending Payment'">
<div class="col-12 col-md-7 padding-20">
<div class="row bg-master-lightest h-100">
<div class="col">
@@ -250,7 +250,7 @@
<div class="font-heading all-caps fs-12">Paid Total:</div>
</div>
<div class="col-auto text-right">
<!-- <div class="font-heading fs-12">MYR {{(Math.round((item.shipping_transaction.paid_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div> -->
<div class="font-heading fs-12" v-if="false">MYR {{(Math.round((item.shipping_transaction.paid_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
<div class="font-heading fs-12">Paid Total</div>
</div>
</div>
@@ -259,7 +259,7 @@
<div class="font-heading all-caps fs-12">Floating Amount:</div>
</div>
<div class="col-auto text-right">
<!-- <div class="font-heading fs-12">MYR {{(Math.round((item.shipping_transaction.floating_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div> -->
<div class="font-heading fs-12" v-if="false">MYR {{(Math.round((item.shipping_transaction.floating_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
<div class="font-heading fs-12">Floating Amount</div>
</div>
</div>
@@ -295,7 +295,7 @@
</div>
</div>
</div>
</div>
</div> -->
</div>
</div>
</template>
@@ -113,7 +113,8 @@
<div class="row tabsContainer tabContent hide" tab-name="pendingPayment" v-if="isActiveTab('pendingPayment') || showTabContent('pendingPayment')">
<div class="col">
<payment-filter-component :endpoint="route('api.packing_list.list')" :data="data"></payment-filter-component>
<admin-payments-billing-with-search-polling-component :options="{has_invoice_status_in: [2], packing_list_limit_one_by_type_ordered_by_invoice_date: true, per_page: 5, check_for_storage_invoice: 1}" section="pendingPaymentSection" invoice_status="Pending Payment" :with_export="true"></admin-payments-billing-with-search-polling-component>
<!-- <admin-payments-billing-with-search-polling-component :options="{has_invoice_status_in: [2], packing_list_limit_one_by_type_ordered_by_invoice_date: true, per_page: 5, check_for_storage_invoice: 1}" section="pendingPaymentSection" invoice_status="Pending Payment" :with_export="true"></admin-payments-billing-with-search-polling-component> -->
<admin-payments-billing-with-search-polling-component :options="{has_invoice_status_in: [2], packing_list_ordered_by_invoice_date: true, per_page: 5, check_for_storage_invoice: 1}" section="pendingPaymentSection" invoice_status="Pending Payment" :with_export="true"></admin-payments-billing-with-search-polling-component>
</div>
</div>
<div class="row tabsContainer tabContent hide" tab-name="paidInvoice" v-if="isActiveTab('paidInvoice') || showTabContent('paidInvoice')">
@@ -113,7 +113,8 @@
<div class="row tabsContainer tabContent hide" tab-name="pendingPayment" v-if="isActiveTab('pendingPayment') || showTabContent('pendingPayment')">
<div class="col">
<payment-filter-component :endpoint="route('api.packing_list.list')" :data="data"></payment-filter-component>
<admin-payments-billing-with-search-component :options="{has_invoice_status_in: [2], packing_list_limit_one_by_type_ordered_by_invoice_date: true, per_page: 5, check_for_storage_invoice: 1, include_packages: true, include_receive_packing_list: true, include_shipping_transaction: true, include_suspended_invoice: true }" section="pendingPaymentSection" invoice_status="Pending Payment" :with_export="true"></admin-payments-billing-with-search-component>
<!-- <admin-payments-billing-with-search-component :options="{has_invoice_status_in: [2], packing_list_limit_one_by_type_ordered_by_invoice_date: true, per_page: 5, check_for_storage_invoice: 1, include_packages: true, include_receive_packing_list: true, include_shipping_transaction: true, include_suspended_invoice: true }" section="pendingPaymentSection" invoice_status="Pending Payment" :with_export="true"></admin-payments-billing-with-search-component> -->
<admin-payments-billing-with-search-component :options="{has_invoice_status_in: [2], packing_list_ordered_by_invoice_date: true, per_page: 5, check_for_storage_invoice: 1, check_for_storage_invoice_asynchronously: 1, include_packages: true, include_receive_packing_list: true, include_shipping_transaction: true, include_suspended_invoice: true }" section="pendingPaymentSection" invoice_status="Pending Payment" :with_export="true"></admin-payments-billing-with-search-component>
</div>
</div>
<div class="row tabsContainer tabContent hide" tab-name="paidInvoice" v-if="isActiveTab('paidInvoice') || showTabContent('paidInvoice')">