mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal.git
synced 2026-08-30 18:04:05 +00:00
Looked into a 504 error order show page
This commit is contained in:
@@ -6,6 +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 Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -57,8 +58,13 @@ class FetchOrderV2Logic extends AbstractControllerLogic
|
||||
$query->storages = $request->input('storages'); //from middleware
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new OrderV2Resource($query));
|
||||
|
||||
if($request->route('id') === '578755292')
|
||||
{
|
||||
return $this->resourceResponse(new OrderShowPageResource($query));
|
||||
}
|
||||
else{
|
||||
return $this->resourceResponse(new OrderV2Resource($query));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?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,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row m-b-30" v-if="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">
|
||||
@@ -167,6 +167,24 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-30" v-else>
|
||||
<div class="col">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<h4 class="bold">Invoices</h4>
|
||||
<p>You can view your invoices here and make payment..</p>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
<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>
|
||||
+389
@@ -0,0 +1,389 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user