mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal.git
synced 2026-08-19 04:24:12 +00:00
365 lines
23 KiB
Vue
365 lines
23 KiB
Vue
<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 padding-20">
|
|
<div class="row align-items-center">
|
|
<div class="col-2">
|
|
<p class="no-margin fs-10 all-caps">Invoice Date</p>
|
|
<div> {{ item.updated_at }}</div>
|
|
</div>
|
|
<div class="col">
|
|
<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-2">
|
|
<p class="no-margin fs-10 all-caps">Amount</p>
|
|
<div>MYR {{ item.amount.toFixed(2) }}</div>
|
|
</div>
|
|
<div class="col-2">
|
|
<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-2 p-l-0 p-r-0 d-flex justify-content-center align-items-center" 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>
|
|
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>
|
|
<div class="col-auto p-l-0 p-r-0 d-flex justify-content-center align-items-center">
|
|
<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>
|
|
<div v-else class="invisible">
|
|
<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 v-if="item.documents.length">
|
|
<div v-for="file in item.documents[0].files" v-bind:key="file.id" class="col-auto no-padding">
|
|
<document-file-viewer-component :file="file">
|
|
<template slot="button">
|
|
<div class="btn bg-grey no-border muted">
|
|
<i class="fa fa-file-pdf-o"></i>
|
|
</div>
|
|
</template>
|
|
</document-file-viewer-component>
|
|
</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>
|
|
<div class="col-auto p-l-0 p-r-0 d-flex justify-content-center align-items-center" v-if="$store.getters.isSuperAdmin">
|
|
|
|
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" style="min-width:15px;" :data-type="'regenerateStorageInvoice-' + item.id" v-if="item.type === 16">
|
|
<i class="fa fa-repeat"></i>
|
|
</span>
|
|
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" style="min-width:15px;" :data-type="'regenerateShippingInvoice-' + item.id" v-else>
|
|
<i class="fa fa-repeat"></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?"
|
|
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?"
|
|
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>
|
|
|
|
<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"></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="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">
|
|
<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 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 class="row b-t b-grey p-t-10 m-l-5 m-r-5" >
|
|
<div class="col-12 col-md-7 padding-20">
|
|
<div class="row bg-master-lightest">
|
|
<div class="col">
|
|
<div v-for="(groupItem, index) in items" class="row bg-master-lightest" v-if="groupItem.groups_payment_attempts.length && groupItem.type == 1 && groupTransactionsExist(items, groupItem.groups_payment_attempts)">
|
|
<div class="col">
|
|
<div class="row m-t-10 m-b-10">
|
|
<div class="col">
|
|
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment Attempt</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<single-group-payment-transaction-details-component v-for="group in groupItem.groups_payment_attempts" v-bind:key="group.id" :data="group" :section="section"></single-group-payment-transaction-details-component>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-for="(groupItem, index) in items" class="row bg-master-lightest" v-if="groupItem.groups_payment_expired.length && groupItem.type == 1 && groupTransactionsExist(items, groupItem.groups_payment_expired)">
|
|
<div class="col">
|
|
<div class="row m-t-10 m-b-10">
|
|
<div class="col">
|
|
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment Expired</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<payment-expired-component v-for="group in groupItem.groups_payment_expired" v-bind:key="group.id" :data="group" :section="section"></payment-expired-component>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-for="(groupItem, index) in items" class="row bg-master-lightest" v-if="groupItem.groups_payment_history.length && groupItem.type == 1 && groupTransactionsExist(items, groupItem.groups_payment_history)">
|
|
<div class="col">
|
|
<div class="row m-t-10 m-b-10">
|
|
<div class="col">
|
|
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment History</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<single-group-payment-history-transaction-details-component v-for="group in groupItem.groups_payment_history" v-bind:key="group.id" :data="group" :section="section"></single-group-payment-history-transaction-details-component>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-for="(paymentAttemptItem, index) in items" class="row bg-master-lightest" v-if="items.some(x => x.payment_attempts && x.payment_attempts.length > 0)">
|
|
<div class="col">
|
|
<div class="row m-t-10 m-b-10">
|
|
<div class="col">
|
|
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment Attempt</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<shipping-transaction-component v-for="i in paymentAttemptItem.payment_attempts" v-bind:key="i.id" :data="i" :section="section"></shipping-transaction-component>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-for="(paymentExpiredItem, index) in items" class="row bg-master-lightest" v-if="items.some(x => x.payments_expired && x.payments_expired.length > 0)">
|
|
<div class="col">
|
|
<div class="row m-t-10 m-b-10">
|
|
<div class="col">
|
|
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment Expired</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<payment-expired-component v-for="i in paymentExpiredItem.payments_expired" v-bind:key="i.id" :data="i" ></payment-expired-component>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-for="(paymentHistoryItem, index) in items" class="row bg-master-lightest" v-if="items.some(x => x.payment_history && x.payment_history.length > 0)">
|
|
<div class="col">
|
|
<div class="row m-t-10 m-b-10">
|
|
<div class="col">
|
|
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment History</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<payment-history-component v-for="i in paymentHistoryItem.payment_history" v-bind:key="i.id" :data="i" ></payment-history-component>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-md-5 padding-20 parentContainer">
|
|
<div class="row bg-master-lightest h-100">
|
|
<div class="col">
|
|
<div class="row padding-10">
|
|
<div class="col">
|
|
<div class="row align-items-end m-b-10 text-complete">
|
|
<div class="col">
|
|
<div class="font-heading all-caps fs-12">Total Amount:</div>
|
|
</div>
|
|
<div class="col-auto text-right">
|
|
<div class="font-heading fs-12">MYR {{(Math.round((totalAmount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
|
</div>
|
|
</div>
|
|
<div class="row align-items-end m-b-10 text-success">
|
|
<div class="col">
|
|
<div class="font-heading all-caps fs-12">Paid Total:</div>
|
|
</div>
|
|
<div class="col-auto text-right">
|
|
<div class="font-heading fs-12">MYR {{(Math.round((totalAmount - totalOutstanding + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
|
</div>
|
|
</div>
|
|
<div class="row align-items-end m-b-10">
|
|
<div class="col">
|
|
<div class="font-heading all-caps fs-12">Floating Amount:</div>
|
|
</div>
|
|
<div class="col-auto text-right">
|
|
<div class="font-heading fs-12">MYR {{(Math.round((totalFloating + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
|
</div>
|
|
</div>
|
|
<div class="row align-items-end bold text-danger">
|
|
<div class="col">
|
|
<div class="font-heading all-caps fs-12">OutStanding Total:</div>
|
|
</div>
|
|
<div class="col-auto text-right">
|
|
<div class="font-heading fs-12">MYR {{(Math.round((totalOutstanding + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
|
</div>
|
|
</div>
|
|
<div class="row m-t-20" v-if="totalOutstanding - totalFloating > 0.009">
|
|
<div class="col">
|
|
<div class="btn btn-sm all-caps b-rad-none btn-success btn-block requestModal" data-type="makePayment">Make Payment</div>
|
|
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="makePayment">
|
|
<group-payment-form-component :section="section" :selectedIds="selectedIds" :sumAmount="totalOutstanding.toFixed(2)" :showManualPayment="true"></group-payment-form-component>
|
|
</modal-component>
|
|
</div>
|
|
</div>
|
|
</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(){
|
|
return {
|
|
items: this.data,
|
|
parameters: {
|
|
packing_list_id: null,
|
|
transaction_details: [],
|
|
},
|
|
expanded: true,
|
|
}
|
|
},
|
|
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;
|
|
},
|
|
},
|
|
methods: {
|
|
getLatestComment(item) {
|
|
let questions = item.remarks;
|
|
return questions.slice().reverse()[0];
|
|
},
|
|
successHandler(response){
|
|
this.item = response.payload.data;
|
|
},
|
|
groupTransactionsExist(items, groups) {
|
|
return groups.some(group =>
|
|
group.transactions_ids.length === items.length &&
|
|
group.transactions_ids.every(transaction =>
|
|
items.some(item => item.id === transaction.transaction_id)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
</script>
|