mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal.git
synced 2026-08-19 04:24:12 +00:00
Looked into a 504 error order show page
This commit is contained in:
@@ -6,8 +6,7 @@ namespace App\Classes\Modules\Orders\ControllersLogic;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Orders\Services\FetchesOrder;
|
||||
use App\Classes\Modules\Orders\Standards\Rules\CanFetchOrder;
|
||||
use App\Http\Resources\OrderShowPageResource;
|
||||
use App\Http\Resources\OrderV2Resource;
|
||||
use App\Http\Resources\FetchOrderResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -49,7 +48,6 @@ class FetchOrderV2Logic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
|
||||
$this->canFetchOrder->passes();
|
||||
|
||||
$query = $this->fetchesOrder->execute(['reference' => $request->route('id'), 'with_packing_lists' => true]);
|
||||
@@ -57,14 +55,6 @@ class FetchOrderV2Logic extends AbstractControllerLogic
|
||||
if($request->input('storages')){
|
||||
$query->storages = $request->input('storages'); //from middleware
|
||||
}
|
||||
|
||||
if($request->route('id') === '578755292')
|
||||
{
|
||||
return $this->resourceResponse(new OrderShowPageResource($query));
|
||||
}
|
||||
else{
|
||||
return $this->resourceResponse(new OrderV2Resource($query));
|
||||
}
|
||||
return $this->resourceResponse(new FetchOrderResource($query));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use App\Classes\Modules\Orders\Services\ListsOrders;
|
||||
use App\Classes\Modules\Orders\Standards\Rules\CanListOrders;
|
||||
use App\Classes\ValueObjects\Constants\OrderType;
|
||||
use App\Http\Resources\OrderBaseResource;
|
||||
use App\Http\Resources\OrderV2Resource;
|
||||
use ErrorException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -65,9 +64,5 @@ class ListOrdersV2Logic extends AbstractControllerLogic
|
||||
}
|
||||
|
||||
return $this->collectionResponse(OrderBaseResource::collection($query));
|
||||
//return $this->collectionResponse(OrderV2Resource::collection($query));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Standards\Rules\CanFetchTransaction;
|
||||
use App\Http\Resources\TransactionWithStorageResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FetchTransactionLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Fetched Transaction',
|
||||
'message' => 'You have successfully retrieved a Transaction'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanFetchTransaction */
|
||||
private $canFetchTransaction;
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
/**
|
||||
* FetchTransactionLogic constructor.
|
||||
* @param CanFetchTransaction $canFetchTransaction
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
*/
|
||||
public function __construct(CanFetchTransaction $canFetchTransaction, FetchesTransaction $fetchesTransaction)
|
||||
{
|
||||
$this->canFetchTransaction = $canFetchTransaction;
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$this->canFetchTransaction->passes();
|
||||
|
||||
$query = $this->fetchesTransaction->execute(['id' => $request->route('transaction_id')]);
|
||||
|
||||
if($request->input('storages')){
|
||||
$query->storages = $request->input('storages'); //from middleware
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new TransactionWithStorageResource($query));
|
||||
}
|
||||
}
|
||||
+4
-5
@@ -17,8 +17,6 @@ use App\Classes\Modules\Transactions\Services\DeletesGroup;
|
||||
use App\Classes\Modules\Billplzs\Services\DeletesBillplzBill;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionDetailObject;
|
||||
|
||||
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
@@ -26,7 +24,6 @@ use App\Classes\ValueObjects\Constants\PackageType;
|
||||
use App\Classes\ValueObjects\Constants\PackingListType;
|
||||
use App\Classes\ValueObjects\Constants\TaxPercentage;
|
||||
use App\Classes\ValueObjects\Constants\TransactionDetailType;
|
||||
use App\Http\Resources\TransactionForOrderShowPageResource;
|
||||
use App\Http\Resources\TransactionWithStorageResource;
|
||||
use App\Models\Order;
|
||||
use App\Models\PackingList;
|
||||
@@ -166,6 +163,7 @@ class CheckStorageInvoiceTransactionProcessor
|
||||
|
||||
/** @var Transaction $invoice_transaction */
|
||||
foreach ($transactions as $invoice_transaction){
|
||||
LogHelper::channel('storage_invoices')->info('invoice_transaction bill_no: '. $invoice_transaction->bill_no);
|
||||
$result = null;
|
||||
if(!$is_credit_term){
|
||||
$result = $this->processSingleTransactionOfTypeShippingInvoice($invoice_transaction, $packingList, $order->company_module_id, $eta);
|
||||
@@ -183,6 +181,7 @@ class CheckStorageInvoiceTransactionProcessor
|
||||
|
||||
private function getArrivalDateAtChinaWarehoue($packingList){
|
||||
if($packingList->type === PackingListType::SHIPPING_PACKING_LIST){
|
||||
LogHelper::channel('storage_invoices')->info('packingList reference: '.json_encode($packingList->reference));
|
||||
$receive_packing_list = PackingList::where('reference', $packingList->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first();
|
||||
LogHelper::channel('storage_invoices')->info('receive_packing_list: '.json_encode($receive_packing_list->transports));
|
||||
$transport = $receive_packing_list->transports->first();
|
||||
@@ -344,7 +343,7 @@ class CheckStorageInvoiceTransactionProcessor
|
||||
'currentDate' => $dt2->format('Y-m-d H:i:s'),
|
||||
'cbm' => $cbm,
|
||||
'pricePerCBM' => $pricePerCBM,
|
||||
'storageInvoice' => new TransactionForOrderShowPageResource($storageInvoice)
|
||||
'storageInvoice' => new TransactionWithStorageResource($storageInvoice)
|
||||
];
|
||||
return $result;
|
||||
}
|
||||
@@ -407,7 +406,7 @@ class CheckStorageInvoiceTransactionProcessor
|
||||
'currentDate' => $resultCurrentDate,
|
||||
'cbm' => $cbm,
|
||||
'pricePerCBM' => $pricePerCBM,
|
||||
'storageInvoice' => new TransactionForOrderShowPageResource($storageInvoice)
|
||||
'storageInvoice' => new TransactionWithStorageResource($storageInvoice)
|
||||
];
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Standards\Rules;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
|
||||
class CanFetchTransaction extends AbstractRule
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return bool
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return bool
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Transactions;
|
||||
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\FetchTransactionLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FetchTransactionController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param FetchTransactionLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function fetch(Request $request, FetchTransactionLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -72,6 +72,7 @@ class Kernel extends HttpKernel
|
||||
'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class,
|
||||
'auth.check' => \App\Http\Middleware\CheckAuthorizationMiddleware::class,
|
||||
'storage.invoice.check.byorder' => \App\Http\Middleware\CheckForStorageInvoiceByOrderId::class,
|
||||
'storage.invoice.check.bytransaction' => \App\Http\Middleware\CheckForStorageInvoiceByTransactionId::class,
|
||||
'storage.invoice.check.bytransactions' => \App\Http\Middleware\CheckForStorageInvoiceByTransactions::class,
|
||||
'storage.invoice.check.bygroup' => \App\Http\Middleware\CheckForStorageInvoiceByGroup::class,
|
||||
'storage.invoice.check.bypackinglists' => \App\Http\Middleware\CheckForStorageInvoiceByPackingLists::class,
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\General\LogHelper;
|
||||
|
||||
class CheckForStorageInvoiceByTransactionId
|
||||
{
|
||||
|
||||
/** @var CheckStorageInvoiceTransactionProcessor */
|
||||
private $storageInvoiceTransactionProcessor;
|
||||
|
||||
|
||||
public function __construct(CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
|
||||
{
|
||||
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$transactionId = $request->route('transaction_id');
|
||||
LogHelper::channel('storage_invoices')->info('CheckForStorageInvoiceByTransactionId: ' . $transactionId);
|
||||
$storages = [];
|
||||
try{
|
||||
$transaction = Transaction::where('id', $transactionId)->first();
|
||||
if($transaction){
|
||||
$storages = $this->storageInvoiceTransactionProcessor->executeShippingTransaction($transaction);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
$storages = [];
|
||||
}
|
||||
$request->merge(['storages' => $storages]);
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,9 @@ namespace App\Http\Resources;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class OrderV2Resource extends JsonResource
|
||||
class FetchOrderResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class OrderShowPageResource 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,
|
||||
'reference_contract' => (int) $this->type,
|
||||
'type' => (int) $this->type,
|
||||
'status' => (int) $this->status,
|
||||
'company_module' => new CompanyModuleResource($this->companyModule),
|
||||
'warehouse' => new CompanyModuleResource($this->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee),
|
||||
'address' => new AddressResource($this->addresses()->where('status', '=', ApprovalStatus::APPROVED)->first()),
|
||||
'address_change_request' => new AddressResource($this->addressesPendingVerification()->first()),
|
||||
'invoices' => $this->whenLoaded('packingLists', function() {
|
||||
$transactions = $this->transactions()->whereNotIn('transactions.status', [0, 1])->whereIn('transactions.type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get();
|
||||
foreach ($transactions as $transaction) {
|
||||
$transaction['is_einvoice_applicable'] = $this->companyModule->company->e_invoice === 1;
|
||||
}
|
||||
return TransactionForOrderShowPageResource::collection($transactions);
|
||||
}),
|
||||
'storages' => $this->storages ? $this->storages : null, //from middleware
|
||||
'remarks' => RemarkResource::collection($this->remarks),
|
||||
'supplier_tax_rebate' => SupplierTaxRebateResource::collection($this->supplierTaxRebate),
|
||||
'created_at' => $this->created_at->format('d-m-Y'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\Group;
|
||||
use App\Models\PackingList;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\Wallet;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class TransactionForOrderShowPageResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$groupTransactions = null;
|
||||
|
||||
if ($this->owner instanceof Transaction) {
|
||||
// if ($this->owner) {
|
||||
// if ($this->owner->owner) {
|
||||
// $order = new OrderResource($this->owner->owner->owner);
|
||||
// }
|
||||
// }
|
||||
} else if (!($this->owner instanceof Transaction) && !($this->owner instanceof Wallet)) {
|
||||
// if ($this->owner) {
|
||||
// $order = new OrderResource($this->owner->owner);
|
||||
// }
|
||||
} else {
|
||||
$group = Group::where('reference', $this->payment_reference)->first();
|
||||
if ($group) {
|
||||
$groupTransactions = GroupTransactionResource::collection($group->groupTransactions);
|
||||
}
|
||||
}
|
||||
|
||||
$packingListReference = null;
|
||||
if ($this->owner instanceof PackingList) {
|
||||
$packingListReference = $this->owner->reference;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'owner_type' => $this->owner_type,
|
||||
'documents' => $groupTransactions ? DocumentResource::collection($this->documents->where('status', ApprovalStatus::PENDING_VERIFICATION)) : DocumentResource::collection($this->documents),
|
||||
'type' => (int) $this->type,
|
||||
'bill_no' => $this->bill_no,
|
||||
'amount' => (double) $this->amount,
|
||||
'payment_method' => (int) $this->payment_method,
|
||||
'payment_reference' => $this->payment_reference,
|
||||
'service_charge' => (double) $this->service_charge,
|
||||
'tax' => (double) $this->tax,
|
||||
'original_amount' => (double) $this->original_amount,
|
||||
'currency_rate' => (double) $this->currency_rate,
|
||||
'status' => (int) $this->status,
|
||||
'remarks' => RemarkResource::collection($this->remarks),
|
||||
'packing_list_reference' => $packingListReference,
|
||||
'storages' => $this->storages ? $this->storages : null, //from middleware
|
||||
'is_waived' => (int) $this->is_waived,
|
||||
'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'),
|
||||
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'),
|
||||
'is_einvoice_applicable' => Carbon::parse($this->created_at)->isAfter(Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'))) && $this->is_einvoice_applicable,
|
||||
];
|
||||
}
|
||||
}
|
||||
+41
-47
@@ -149,7 +149,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row m-b-30" v-if="(order.reference != '578755292') && order.invoices.length">
|
||||
<!-- <div class="row m-b-30" v-if="(order.reference != '578755292') && order.invoices.length">
|
||||
<div class="col">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
@@ -166,8 +166,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-30" v-else>
|
||||
</div> -->
|
||||
<div class="row m-b-30" v-if="order.invoices.length">
|
||||
<div class="col">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
@@ -176,19 +176,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row bg-master-lightest p-t-15" v-for="invoice in order.invoices" v-if="invoice.type === 1">
|
||||
<div class="col" v-if="getMergedInvoices(invoice).length > 1">
|
||||
<cust-pay-bill-with-storage-component :data="getMergedInvoices(invoice)" :storage="getStorageInfo(invoice)" invoice_status="Pending Payment" :section="section"></cust-pay-bill-with-storage-component>
|
||||
</div>
|
||||
<div class="col" v-else>
|
||||
<cust-pay-bill-component :data="invoice" invoice_status="Pending Payment" :section="section"></cust-pay-bill-component>
|
||||
</div>
|
||||
<cust-pay-bill-parent-component :data="invoice" :section="section"></cust-pay-bill-parent-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<order-package-v3-section-component
|
||||
v-if="!isLoading && showOld"
|
||||
:order_number="order_number">
|
||||
@@ -224,16 +218,16 @@
|
||||
pendingQueue () {
|
||||
return this.$store.getters.isInCompleteQueue(this.section);
|
||||
},
|
||||
orderStorageMap() {
|
||||
// Create a map to link parent invoice IDs to storageInvoiceIds
|
||||
const storageMap = {};
|
||||
if(this.order.storages){
|
||||
for (const storage of this.order.storages) {
|
||||
storageMap[storage.parentInvoiceId] = storage.storageInvoiceId;
|
||||
}
|
||||
}
|
||||
return storageMap;
|
||||
}
|
||||
// orderStorageMap() {
|
||||
// // Create a map to link parent invoice IDs to storageInvoiceIds
|
||||
// const storageMap = {};
|
||||
// if(this.order.storages){
|
||||
// for (const storage of this.order.storages) {
|
||||
// storageMap[storage.parentInvoiceId] = storage.storageInvoiceId;
|
||||
// }
|
||||
// }
|
||||
// return storageMap;
|
||||
// }
|
||||
},
|
||||
watch: {
|
||||
pendingQueue(inComplete){
|
||||
@@ -264,35 +258,35 @@
|
||||
window.location.href = this.route('error.404');
|
||||
}
|
||||
},
|
||||
getStorageInfo(invoice) {
|
||||
const storageObject = this.findStorageInfoObject(invoice.id);
|
||||
return storageObject;
|
||||
},
|
||||
findStorageInfoObject(shippingInvoiceId) {
|
||||
if(this.order.storages){
|
||||
return this.order.storages.find(storage => storage.parentInvoiceId === shippingInvoiceId);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getMergedInvoices(invoice){
|
||||
const storageInvoice = this.getStorageInvoice(invoice);
|
||||
const mergedArray = [
|
||||
...(invoice ? [invoice] : []),
|
||||
...(storageInvoice ? [storageInvoice] : []),
|
||||
];
|
||||
return mergedArray;
|
||||
},
|
||||
getStorageInvoice(invoice) {
|
||||
// Retrieve the storageInvoiceId for the current shipping invoice from storage info (order.storages)
|
||||
const storageInvoiceId = this.orderStorageMap[invoice.id];
|
||||
// getStorageInfo(invoice) {
|
||||
// const storageObject = this.findStorageInfoObject(invoice.id);
|
||||
// return storageObject;
|
||||
// },
|
||||
// findStorageInfoObject(shippingInvoiceId) {
|
||||
// if(this.order.storages){
|
||||
// return this.order.storages.find(storage => storage.parentInvoiceId === shippingInvoiceId);
|
||||
// }
|
||||
// return null;
|
||||
// },
|
||||
// getMergedInvoices(invoice){
|
||||
// const storageInvoice = this.getStorageInvoice(invoice);
|
||||
// const mergedArray = [
|
||||
// ...(invoice ? [invoice] : []),
|
||||
// ...(storageInvoice ? [storageInvoice] : []),
|
||||
// ];
|
||||
// return mergedArray;
|
||||
// },
|
||||
// getStorageInvoice(invoice) {
|
||||
// // Retrieve the storageInvoiceId for the current shipping invoice from storage info (order.storages)
|
||||
// const storageInvoiceId = this.orderStorageMap[invoice.id];
|
||||
|
||||
// Find and return the storage invoice (type 16) from order.invoices
|
||||
const storageInvoice = this.order.invoices.find((invoice) => {
|
||||
return invoice.type === 16 && invoice.id === storageInvoiceId;
|
||||
});
|
||||
// // Find and return the storage invoice (type 16) from order.invoices
|
||||
// const storageInvoice = this.order.invoices.find((invoice) => {
|
||||
// return invoice.type === 16 && invoice.id === storageInvoiceId;
|
||||
// });
|
||||
|
||||
return storageInvoice;
|
||||
},
|
||||
// return storageInvoice;
|
||||
// },
|
||||
download(param) {
|
||||
let url = route('order.qr.download', param.id);
|
||||
if(window.LARAVEL_VAPOR_ENABLED){
|
||||
|
||||
@@ -1,314 +0,0 @@
|
||||
<template>
|
||||
<div class="row m-b-15 m-l-5 m-r-10 parentContainer">
|
||||
<div class="col bg-white rounded">
|
||||
<div class="row justify-content-end" v-if="item.type === 1 && $store.getters.isSuperAdmin">
|
||||
<!-- <div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" data-type="deleteInvoice">Delete</div> -->
|
||||
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="deleteInvoice">
|
||||
<i class="fa fa-close fa-2x"></i>
|
||||
</span>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deleteInvoice">
|
||||
<delete-invoice-form-component :data="item" :section="section"></delete-invoice-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="row" :class="[{'b-danger': item.status == 5 ||item.status == 6, 'b-a': item.status == 5||item.status == 6}]">
|
||||
<div class="col">
|
||||
<div class="row padding-20 align-items-center">
|
||||
<div class="col-auto">
|
||||
<p class="no-margin fs-10 all-caps">Invoice Date</p>
|
||||
<div> {{ item.created_at }}</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<p class="no-margin fs-10 all-caps">Status</p>
|
||||
<div class="all-caps" v-if="item.status == 3">Payment Completed</div>
|
||||
<div class="all-caps text-danger" v-else-if="item.status == 5">Dispute in progress</div>
|
||||
<div class="all-caps" v-else-if="item.status == 6">Cancelled Invoice</div>
|
||||
<div class="all-caps" v-else>Pending Payment</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<p class="no-margin fs-10 all-caps">Amount</p>
|
||||
<div>MYR {{ item.amount.toFixed(2) }}</div>
|
||||
</div>
|
||||
<div class="col" v-if="item.remarks.length">
|
||||
<p class="no-margin fs-10 all-caps">Billing Question</p>
|
||||
<div>
|
||||
{{ latestComment.content }}
|
||||
<span class="btn requestModal no-border" v-if="item.remarks.length" size="large" data-type="chatmodal">
|
||||
<i class="fa fa-comment-o"></i>
|
||||
</span>
|
||||
</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="chatmodal">
|
||||
<remark-component :section="section" :data="item" module_type="Transaction"></remark-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="col" v-else>
|
||||
<p class="no-margin fs-10 all-caps invisible">Billing Question</p>
|
||||
<div>
|
||||
<span class="btn requestModal no-border invisible">
|
||||
<i class="fa fa-edit"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div :class="[{'invisible': [5, 6, 3].includes(item.status)}]">
|
||||
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="billingRemark">Billing Question?</span>
|
||||
</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="billingRemark">
|
||||
<customer-invoice-remark-form-component module_type="Transaction" :data="item" :section="section"></customer-invoice-remark-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
|
||||
<!-- PDF - INV -->
|
||||
<div class="col-auto" v-if="!isEinvoiceApplicable">
|
||||
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SHIPPING_INVOICE')">
|
||||
<div v-for="doc in item.documents.filter(d => d.document_type === 'SHIPPING_INVOICE')" :key="doc.id">
|
||||
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
|
||||
<document-file-viewer-component :file="file">
|
||||
<template slot="button">
|
||||
<div class="bg-grey no-border muted">
|
||||
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
|
||||
<path d="M28 0v8h8z" fill="#1e8449"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="13" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">INV</text>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="btn bg-grey no-border muted invisible">
|
||||
<i class="fa fa-file-pdf-o"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PDF - EINV -->
|
||||
<div class="col-auto" v-if="isEinvoiceApplicable">
|
||||
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SHIPPING_EINVOICE')">
|
||||
<div v-for="doc in item.documents.filter(d => d.document_type === 'SHIPPING_EINVOICE')" :key="doc.id">
|
||||
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
|
||||
<document-file-viewer-component :file="file">
|
||||
<template slot="button">
|
||||
<div class="bg-grey no-border muted">
|
||||
<svg width="48" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
|
||||
<path d="M28 0v8h8z" fill="#1e8449"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="12" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">EINV</text>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<!-- <div class="btn bg-grey no-border muted invisible">
|
||||
<i class="fa fa-file-pdf-o"></i>
|
||||
</div> -->
|
||||
<div class="bg-grey no-border muted">
|
||||
<svg width="48" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
|
||||
<path d="M28 0v8h8z" fill="#95a5a6"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="12" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">EINV</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PDF - SO -->
|
||||
<div class="col-auto">
|
||||
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SALES_ORDER')">
|
||||
<div v-for="doc in item.documents.filter(d => d.document_type === 'SALES_ORDER')" :key="doc.id">
|
||||
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
|
||||
<document-file-viewer-component :file="file">
|
||||
<template slot="button">
|
||||
<div class="bg-grey no-border muted">
|
||||
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
|
||||
<path d="M28 0v8h8z" fill="#1e8449"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="14" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">SO</text>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<!-- <div class="btn bg-grey no-border muted invisible">
|
||||
<i class="fa fa-file-pdf-o"></i>
|
||||
</div> -->
|
||||
<div class="bg-grey no-border muted">
|
||||
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
|
||||
<path d="M28 0v8h8z" fill="#95a5a6"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="14" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">SO</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- cief todo: 90 - why hide??? -->
|
||||
<!-- <div class="col-auto hide">
|
||||
<div class="btn btn-sm all-caps b-rad-none btn-block" :class="{'btn-success': !expanded, 'btn-default': expanded}" @click="expanded = !expanded">
|
||||
{{ expanded ? 'Cancel' : 'Make Payment' }}</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="$store.getters.isAdmin">
|
||||
<div class="col">
|
||||
<div class="row padding-20">
|
||||
<div class="col">
|
||||
<p class="no-margin fs-10 all-caps">Packinglist Reference</p>
|
||||
<div>
|
||||
<a :href="route('order.tracking', item.packing_list_reference)" target="_blank">
|
||||
{{ item.packing_list_reference }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto d-flex justify-content-center align-items-center" v-if="$store.getters.isSuperAdmin">
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" data-type="regenerateInvoice" v-if="!isEinvoiceApplicable">Regenerate Invoice PDF</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="regenerateInvoice">
|
||||
<general-confirmation-form-component
|
||||
contentText="Are you sure you want to regenerate this Invoice PDF document?"
|
||||
modalType="delete"
|
||||
buttonText="Regenerate"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.transaction.invoice.regenerate', item.id)"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" data-type="regenerateEInvoice" v-if="isEinvoiceApplicable">Regenerate E-Invoice PDF</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="regenerateEInvoice">
|
||||
<general-confirmation-form-component
|
||||
contentText="Are you sure you want to regenerate this E-Invoice PDF document?"
|
||||
modalType="delete"
|
||||
buttonText="Regenerate"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.transaction.einvoice.regenerate', item.id)"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" data-type="regenerateSalesOrder">Regenerate Sales Order PDF</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="regenerateSalesOrder">
|
||||
<general-confirmation-form-component
|
||||
contentText="Are you sure you want to regenerate this Sales Order PDF document?"
|
||||
modalType="delete"
|
||||
buttonText="Regenerate"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.transaction.sales.order.regenerate', item.id)"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
export default {
|
||||
props: {
|
||||
invoice_status: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
parameters: {
|
||||
packing_list_id: null,
|
||||
transaction_details: [],
|
||||
},
|
||||
expanded: true,
|
||||
showPaymentProceedModal: false,
|
||||
showPaymentOutdatedModal: false,
|
||||
isEinvoiceApplicable: this.data.is_einvoice_applicable,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// cbm () {
|
||||
// return (Math.ceil((this.item.packages.reduce((total, obj) => (obj.type === 2 ? 0 : obj.cbm) + total, 0)) * 1000) / 1000).toFixed(3)
|
||||
// },
|
||||
// overweight(){
|
||||
// return (Math.ceil((this.item.packages.reduce((total, obj) => (obj.type === 2 ? obj.cbm : 0) + total, 0)) * 1000) / 1000).toFixed(3)
|
||||
// },
|
||||
latestComment() {
|
||||
let questions = this.item.remarks;
|
||||
return questions.slice().reverse()[0];
|
||||
},
|
||||
paymentPending(){
|
||||
if (Array.isArray(this.item.transactions)) {
|
||||
for (let i = 0; i < this.item.transactions.length; i++) {
|
||||
const status = this.item.transactions[i].status;
|
||||
if (status === 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.parameters.packing_list_id = this.data.id;
|
||||
},
|
||||
methods: {
|
||||
handleMakePaymentClick(event) {
|
||||
let selectedShippingInvoicesOnlyIds = [];
|
||||
this.showPaymentProceedModal = false;
|
||||
this.showPaymentOutdatedModal = false;
|
||||
selectedShippingInvoicesOnlyIds.push(this.item.id);
|
||||
this.submit(this.route('api.transaction.verify.transactions', JSON.stringify(selectedShippingInvoicesOnlyIds)), 'get', 'verifyPaymentForOrderProfileV2Section', false, false);
|
||||
},
|
||||
successHandler(response, section){
|
||||
if(section === "verifyPaymentForOrderProfileV2Section")
|
||||
{
|
||||
const totalAmount = response.payload.data.reduce((total, item) => {
|
||||
const topLevelAmount = item.amount || 0;
|
||||
const storagesAmount = item.storages ? item.storages.reduce((sum, storage) => {
|
||||
const storageInvoiceAmount = storage.storageInvoice?.amount || 0;
|
||||
return sum + storageInvoiceAmount;
|
||||
}, 0) : 0;
|
||||
|
||||
return total + topLevelAmount + storagesAmount;
|
||||
|
||||
}, 0);
|
||||
|
||||
const epsilon = 0.0001;
|
||||
if(Math.abs(this.item.outstanding - totalAmount) < epsilon){
|
||||
this.showPaymentProceedModal = true;
|
||||
}
|
||||
else{
|
||||
this.showPaymentOutdatedModal = true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
this.item = response.payload.data;
|
||||
// this.$forceUpdate();
|
||||
}
|
||||
},
|
||||
paymentOutdated(){
|
||||
this.showPaymentProceedModal = false;
|
||||
this.showPaymentOutdatedModal = true;
|
||||
}
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
</script>
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<div class="col">
|
||||
<loading-component style="height: 200px; top: 0;" v-if="isLoading"></loading-component>
|
||||
<div class="row flex-wrap" v-if="!isLoading && transaction">
|
||||
<div class="col" v-if="getMergedInvoices(transaction).length > 1">
|
||||
<customer-payments-billing-with-storage-component :data="getMergedInvoices(transaction)" :storage="getStorageInfo(transaction)" invoice_status="Pending Payment" :section="section"></customer-payments-billing-with-storage-component>
|
||||
</div>
|
||||
<div class="col" v-else>
|
||||
<customer-payments-billing-component :data="transaction" invoice_status="Pending Payment" :section="section"></customer-payments-billing-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
section: 'orderCustomerPaymentBillingSection-' + this.data.id,
|
||||
isLoading: true,
|
||||
transaction: null,
|
||||
storage: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pendingQueue () {
|
||||
return this.$store.getters.isInCompleteQueue(this.section);
|
||||
},
|
||||
orderStorageMap() {
|
||||
// Create a map to link parent invoice IDs to storageInvoiceIds
|
||||
const storageMap = {};
|
||||
if(this.transaction.storages){
|
||||
for (const storage of this.transaction.storages) {
|
||||
storageMap[storage.parentInvoiceId] = storage.storageInvoiceId;
|
||||
}
|
||||
}
|
||||
return storageMap;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pendingQueue(inComplete){
|
||||
if(inComplete){
|
||||
this.fetchTransaction();
|
||||
}
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.$store.dispatch('updateListQueue', {'name': this.section});
|
||||
},
|
||||
methods: {
|
||||
fetchTransaction(){
|
||||
this.isLoading = true;
|
||||
this.submit(route('api.transaction.fetch', this.data.id), 'get', this.section, false, false)
|
||||
},
|
||||
successHandler(response){
|
||||
this.$store.dispatch('completeList', {'name': this.section, 'data': []});
|
||||
this.isLoading = false;
|
||||
this.transaction = response.payload.data;
|
||||
this.storage = response.payload.data.storages?.[0] ?? null;
|
||||
},
|
||||
getStorageInfo(invoice) {
|
||||
const storageObject = this.findStorageInfoObject(invoice.id);
|
||||
return storageObject;
|
||||
},
|
||||
findStorageInfoObject(shippingInvoiceId) {
|
||||
if(this.transaction.storages){
|
||||
return this.transaction.storages.find(storage => storage.parentInvoiceId === shippingInvoiceId);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getMergedInvoices(invoice){
|
||||
const storageInvoice = this.storage?.storageInvoice ?? null;
|
||||
const mergedArray = [
|
||||
...(invoice ? [invoice] : []),
|
||||
...(storageInvoice ? [storageInvoice] : []),
|
||||
];
|
||||
return mergedArray;
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
</script>
|
||||
-389
@@ -1,389 +0,0 @@
|
||||
<template>
|
||||
<div class="row m-b-15 m-l-5 m-r-10 parentContainer">
|
||||
<div class="col bg-white rounded">
|
||||
<div v-for="item in items" class="row" :class="[{'b-danger': item.status == 5 ||item.status == 6, 'b-a': item.status == 5||item.status == 6}]">
|
||||
<div class="col">
|
||||
<div class="row justify-content-end" v-if="item.type === 1 && $store.getters.isSuperAdmin">
|
||||
<!-- <div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'deleteInvoice-' + item.id" v-if="item.type === 1">Delete</div> -->
|
||||
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" :data-type="'deleteInvoice-' + item.id">
|
||||
<i class="fa fa-close fa-2x"></i>
|
||||
</span>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'deleteInvoice-' + item.id">
|
||||
<delete-invoice-form-component :data="item" :section="section"></delete-invoice-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="row padding-20 align-items-center">
|
||||
<div class="col-auto">
|
||||
<p class="no-margin fs-10 all-caps">Invoice Date</p>
|
||||
<div> {{ item.created_at }}</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<p class="no-margin fs-10 all-caps">Status</p>
|
||||
<div class="all-caps" v-if="item.status == 3">Payment Completed</div>
|
||||
<div class="all-caps text-danger" v-else-if="item.status == 5">Dispute in progress</div>
|
||||
<div class="all-caps" v-else-if="item.status == 6">Cancelled Invoice</div>
|
||||
<div class="all-caps" v-else>Pending Payment</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<p class="no-margin fs-10 all-caps">Amount</p>
|
||||
<div>MYR {{ item.amount.toFixed(2) }}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div v-if="item.remarks.length">
|
||||
<p class="no-margin fs-10 all-caps">Billing Question</p>
|
||||
<div>
|
||||
{{ getLatestComment(item).content }}
|
||||
<span class="btn requestModal no-border" v-if="item.remarks.length" size="large" data-type="chatmodal">
|
||||
<i class="fa fa-comment-o"></i>
|
||||
</span>
|
||||
</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="chatmodal">
|
||||
<remark-component :section="section" :data="item" module_type="Transaction"></remark-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p class="no-margin fs-10 all-caps invisible">Billing Question</p>
|
||||
<div>
|
||||
<span class="btn requestModal no-border invisible">
|
||||
<i class="fa fa-edit"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div v-if="item.type === 1" :class="[{'invisible': [5, 6, 3].includes(item.status)}]">
|
||||
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="billingRemark">Billing Question?</span>
|
||||
</div>
|
||||
<modal-component v-if="item.type === 1" class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="billingRemark">
|
||||
<customer-invoice-remark-form-component module_type="Transaction" :data="item" :section="section"></customer-invoice-remark-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="col-auto" v-if="$store.getters.isAdmin">
|
||||
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" v-if="item.type === 16 && item.is_waived === 0 && item.status === 2" :data-type="'waiveInvoice-' + item.id">
|
||||
Waive Transaction
|
||||
</span>
|
||||
<span class="d-inline-block m-r-15 text-primary bold" v-else-if="item.type === 16 && item.is_waived === 1">
|
||||
Transaction Waived
|
||||
</span>
|
||||
<span class="d-inline-block m-r-15 text-primary bold" v-else>
|
||||
Waive N/A
|
||||
</span>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" v-if="item.type === 16 && item.is_waived === 0 && item.status === 2" :type="'waiveInvoice-' + item.id">
|
||||
<waive-invoice-form-component :data="item" :section="section"></waive-invoice-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
|
||||
<!-- PDF - INV: SHIP + STOR -->
|
||||
<div class="col-auto" v-if="!isEinvoiceApplicable">
|
||||
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SHIPPING_INVOICE' || d.document_type === 'STORAGE_INVOICE')">
|
||||
<div v-for="doc in item.documents.filter(d => d.document_type === 'SHIPPING_INVOICE' || d.document_type === 'STORAGE_INVOICE')" :key="doc.id">
|
||||
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
|
||||
<document-file-viewer-component :file="file">
|
||||
<template slot="button">
|
||||
<div class="bg-grey no-border muted">
|
||||
<!-- <i class="fa fa-file-pdf-o"></i> -->
|
||||
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
|
||||
<path d="M28 0v8h8z" fill="#1e8449"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="13" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">INV</text>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="bg-grey no-border muted invisible">
|
||||
<!-- <i class="fa fa-file-pdf-o"></i> -->
|
||||
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
|
||||
<path d="M28 0v8h8z" fill="#95a5a6"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="13" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">INV</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PDF - EINV -->
|
||||
<div class="col-auto" v-if="isEinvoiceApplicable">
|
||||
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SHIPPING_EINVOICE')">
|
||||
<div v-for="doc in item.documents.filter(d => d.document_type === 'SHIPPING_EINVOICE')" :key="doc.id">
|
||||
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
|
||||
<document-file-viewer-component :file="file">
|
||||
<template slot="button">
|
||||
<div class="bg-grey no-border muted">
|
||||
<svg width="48" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
|
||||
<path d="M28 0v8h8z" fill="#1e8449"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="12" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">EINV</text>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="bg-grey no-border muted">
|
||||
<svg width="48" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
|
||||
<path d="M28 0v8h8z" fill="#95a5a6"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="12" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">EINV</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PDF - SO -->
|
||||
<div class="col-auto">
|
||||
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SALES_ORDER')">
|
||||
<div v-for="doc in item.documents.filter(d => d.document_type === 'SALES_ORDER')" :key="doc.id">
|
||||
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
|
||||
<document-file-viewer-component :file="file">
|
||||
<template slot="button">
|
||||
<div class="bg-grey no-border muted">
|
||||
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
|
||||
<path d="M28 0v8h8z" fill="#1e8449"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="14" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">SO</text>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="bg-grey no-border muted">
|
||||
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
|
||||
<path d="M28 0v8h8z" fill="#95a5a6"/>
|
||||
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="14" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">SO</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- cief todo: 90 - why hide??? -->
|
||||
<!-- <div class="col-1 hide">
|
||||
<div class="btn btn-sm all-caps b-rad-none btn-block" :class="{'btn-success': !expanded, 'btn-default': expanded}" @click="expanded = !expanded">
|
||||
{{ expanded ? 'Cancel' : 'Make Payment' }}</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="row p-t-0 p-b-0 p-l-20 p-r-20">
|
||||
<div class="col" v-if="storage" v-show="item.type === 16">
|
||||
<p >Warehouse Storage Fee: {{ storage.numberOfDaysExceeded }} Days x RM {{ storage.pricePerCBM}} x {{ storage.cbm.toFixed(3) }} cbm</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="$store.getters.isAdmin">
|
||||
<div class="col">
|
||||
<div class="row padding-20">
|
||||
<div class="col"></div>
|
||||
<div class="col-auto d-flex justify-content-center align-items-center" v-if="$store.getters.isSuperAdmin">
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'regenerateStorageInvoice-' + item.id" v-if="item.type === 16 && item.status === 3">Regenerate Storage Invoice PDF</div>
|
||||
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'regenerateShippingInvoice-' + item.id" v-if="item.type === 1 && !isEinvoiceApplicable">Regenerate Shipping Invoice PDF</div>
|
||||
|
||||
<!-- <span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" style="min-width:15px;" v-if="item.type === 16 && item.status !== 3">
|
||||
<i class="fa fa-ban"></i>
|
||||
</span> -->
|
||||
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateStorageInvoice-' + item.id" v-if="item.type === 16">
|
||||
<general-confirmation-form-component
|
||||
contentText="Are you sure you want to regenerate this Storage Invoice PDF document?"
|
||||
modalType="delete"
|
||||
buttonText="Regenerate"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.transaction.storage.invoice.regenerate', item.id)"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateShippingInvoice-' + item.id" v-else>
|
||||
<general-confirmation-form-component
|
||||
contentText="Are you sure you want to regenerate this Invoice PDF document?"
|
||||
modalType="delete"
|
||||
buttonText="Regenerate"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.transaction.invoice.regenerate', item.id)"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'regenerateEInvoice-' + item.id" v-if="item.type === 1 && isEinvoiceApplicable">Regenerate E-Invoice PDF</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateEInvoice-' + item.id">
|
||||
<general-confirmation-form-component
|
||||
contentText="Are you sure you want to regenerate this E-Invoice PDF document?"
|
||||
modalType="delete"
|
||||
buttonText="Regenerate"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.transaction.einvoice.regenerate', item.id)"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'regenerateSalesOrder-' + item.id" v-if="item.type === 1">Regenerate Sales Order PDF</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateSalesOrder-' + item.id">
|
||||
<general-confirmation-form-component
|
||||
contentText="Are you sure you want to regenerate this Sales Order PDF document?"
|
||||
modalType="delete"
|
||||
buttonText="Regenerate"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.transaction.sales.order.regenerate', item.id)"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row b-t b-grey p-t-10 m-l-5 m-r-5" v-show="expanded" v-if="[5, 6].includes(item.status)">
|
||||
<div class="col padding-20">
|
||||
<div class="row bg-master-lightest h-100 padding-20">
|
||||
<div class="col">
|
||||
<h6 class="all-caps m-b-5 no-margin text-underline bold">Billing question</h6>
|
||||
<remark-component :section="section" :data="item" module_type="Transaction"></remark-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
},
|
||||
invoice_status: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
storage:{
|
||||
type: Object
|
||||
},
|
||||
},
|
||||
data(){
|
||||
const data = this.data;
|
||||
const match = data.find(item => item.bill_no.startsWith('SHIP'));
|
||||
|
||||
return {
|
||||
items: data,
|
||||
parameters: {
|
||||
packing_list_id: null,
|
||||
transaction_details: [],
|
||||
},
|
||||
expanded: true,
|
||||
showPaymentProceedModal: false,
|
||||
showPaymentOutdatedModal: false,
|
||||
selectedShippingInvoicesOnlyIds: [],
|
||||
isEinvoiceApplicable: match ? match.is_einvoice_applicable : false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
data: function() {
|
||||
this.items = this.data;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalAmount() {
|
||||
return this.items.reduce((sum, item) => sum + item.amount, 0);
|
||||
},
|
||||
totalOutstanding() {
|
||||
return this.items.reduce((sum, item) => sum + item.outstanding, 0);
|
||||
},
|
||||
totalFloating() {
|
||||
return this.items.reduce((sum, item) => sum + item.floating, 0);
|
||||
},
|
||||
selectedIds() {
|
||||
const ids = [];
|
||||
this.items.forEach(item => {
|
||||
ids.push(item.id);
|
||||
});
|
||||
return ids;
|
||||
},
|
||||
groupPaymentPending(){
|
||||
if (Array.isArray(this.items)) {
|
||||
for (let i = 0; i < this.items.length; i++) {
|
||||
for (let j = 0; j < this.items[i].groups_payment_history.length; j++) {
|
||||
const item = this.items[i].groups_payment_history[j];
|
||||
// console.log('item', JSON.stringify(item));
|
||||
if (item.payment_transaction && item.payment_transaction.status === 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getLatestComment(item) {
|
||||
let questions = item.remarks;
|
||||
return questions.slice().reverse()[0];
|
||||
},
|
||||
groupTransactionsExist(items, groups) {
|
||||
return groups.some(group =>
|
||||
group.payment_transaction &&
|
||||
group.transactions_ids.length === items.length &&
|
||||
group.transactions_ids.every(transaction =>
|
||||
items.some(item => item.id === transaction.transaction_id)
|
||||
)
|
||||
);
|
||||
},
|
||||
handleMakePaymentClick(event) {
|
||||
this.showPaymentProceedModal = false;
|
||||
this.showPaymentOutdatedModal = false;
|
||||
this.selectedShippingInvoicesOnlyIds = this.items.filter(invoice => invoice.type === 1).map(s=>s.id);
|
||||
this.submit(this.route('api.transaction.verify.transactions', JSON.stringify(this.selectedShippingInvoicesOnlyIds)), 'get', 'verifyPaymentForOrderProfileV2Section', false, false);
|
||||
},
|
||||
successHandler(response, section){
|
||||
if(section === "verifyPaymentForOrderProfileV2Section")
|
||||
{
|
||||
const totalAmount = response.payload.data.reduce((total, item) => {
|
||||
const topLevelAmount = item.amount || 0;
|
||||
const storagesAmount = item.storages ? item.storages.reduce((sum, storage) => {
|
||||
const storageInvoiceAmount = storage.storageInvoice?.amount || 0;
|
||||
return sum + storageInvoiceAmount;
|
||||
}, 0) : 0;
|
||||
|
||||
return total + topLevelAmount + storagesAmount;
|
||||
|
||||
}, 0);
|
||||
|
||||
const epsilon = 0.0001;
|
||||
if(Math.abs(this.totalOutstanding - totalAmount) < epsilon){
|
||||
this.showPaymentProceedModal = true;
|
||||
}
|
||||
else{
|
||||
this.showPaymentOutdatedModal = true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
this.item = response.payload.data;
|
||||
}
|
||||
},
|
||||
paymentOutdated(){
|
||||
this.showPaymentProceedModal = false;
|
||||
this.showPaymentOutdatedModal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
+2
-2
@@ -4,8 +4,8 @@ use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::group(['prefix' => 'order', 'as' => 'order.', 'namespace' => 'Orders'], function () {
|
||||
Route::get('/show/{id}', 'FetchOrderController@fetch')->name('show');
|
||||
// Route::get('/v2/show/{id}', 'FetchOrderV2Controller@fetch')->name('v2.show');
|
||||
Route::get('/v2/show/{id}', 'FetchOrderV2Controller@fetch')->middleware('storage.invoice.check.byorder')->name('v2.show');
|
||||
Route::get('/v2/show/{id}', 'FetchOrderV2Controller@fetch')->name('v2.show');
|
||||
// Route::get('/v2/show/{id}', 'FetchOrderV2Controller@fetch')->middleware('storage.invoice.check.byorder')->name('v2.show');
|
||||
Route::get('/list', 'ListOrdersController@list')->name('list');
|
||||
Route::get('/v2/list', 'ListOrdersV2Controller@list')->name('v2.list');
|
||||
Route::post('/create', 'CreateOrderController@create')->name('create');
|
||||
|
||||
@@ -58,4 +58,6 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' =>
|
||||
// Route::post('/bulk/po', 'CreateBulkPurchaseOrderDocumentController@create')->name('bulk.po');
|
||||
});
|
||||
|
||||
Route::get('/single/{transaction_id}', 'FetchTransactionController@fetch')->middleware('storage.invoice.check.bytransaction')->name('fetch');
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user