mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-28 04:01:10 -04:00
Merge branch 'resend-email' into 'master'
Add Resend Email Option See merge request mohit.panjvani/crater-web!236
This commit is contained in:
@ -1,16 +1,16 @@
|
|||||||
export default {
|
export default {
|
||||||
toggleSidebar () {
|
toggleSidebar() {
|
||||||
let icon = document.getElementsByClassName('hamburger')[0]
|
let icon = document.getElementsByClassName('hamburger')[0]
|
||||||
document.body.classList.toggle('sidebar-open')
|
document.body.classList.toggle('sidebar-open')
|
||||||
icon.classList.toggle('is-active')
|
icon.classList.toggle('is-active')
|
||||||
},
|
},
|
||||||
|
|
||||||
addClass (el, className) {
|
addClass(el, className) {
|
||||||
if (el.classList) el.classList.add(className)
|
if (el.classList) el.classList.add(className)
|
||||||
else el.className += ' ' + className
|
else el.className += ' ' + className
|
||||||
},
|
},
|
||||||
|
|
||||||
hasClass (el, className) {
|
hasClass(el, className) {
|
||||||
const hasClass = el.classList
|
const hasClass = el.classList
|
||||||
? el.classList.contains(className)
|
? el.classList.contains(className)
|
||||||
: new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className)
|
: new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className)
|
||||||
@ -18,33 +18,38 @@ export default {
|
|||||||
return hasClass
|
return hasClass
|
||||||
},
|
},
|
||||||
|
|
||||||
reset (prefix) {
|
reset(prefix) {
|
||||||
let regx = new RegExp('\\b' + prefix + '(.*)?\\b', 'g')
|
let regx = new RegExp('\\b' + prefix + '(.*)?\\b', 'g')
|
||||||
document.body.className = document.body.className.replace(regx, '')
|
document.body.className = document.body.className.replace(regx, '')
|
||||||
},
|
},
|
||||||
|
|
||||||
setLayout (layoutName) {
|
setLayout(layoutName) {
|
||||||
this.reset('layout-')
|
this.reset('layout-')
|
||||||
document.body.classList.add('layout-' + layoutName)
|
document.body.classList.add('layout-' + layoutName)
|
||||||
},
|
},
|
||||||
|
|
||||||
setSkin (skinName) {
|
setSkin(skinName) {
|
||||||
this.reset('skin-')
|
this.reset('skin-')
|
||||||
document.body.classList.add('skin-' + skinName)
|
document.body.classList.add('skin-' + skinName)
|
||||||
},
|
},
|
||||||
|
|
||||||
setLogo (logoSrc) {
|
setLogo(logoSrc) {
|
||||||
document.getElementById('logo-desk').src = logoSrc
|
document.getElementById('logo-desk').src = logoSrc
|
||||||
},
|
},
|
||||||
|
|
||||||
formatMoney (amount, currency = 0) {
|
formatMoney(amount, currency = 0) {
|
||||||
if (!currency) {
|
if (!currency) {
|
||||||
currency = {precision: 2, thousand_separator: ',', decimal_separator: '.', symbol: '$'}
|
currency = {
|
||||||
|
precision: 2,
|
||||||
|
thousand_separator: ',',
|
||||||
|
decimal_separator: '.',
|
||||||
|
symbol: '$',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
amount = amount / 100
|
amount = amount / 100
|
||||||
|
|
||||||
let {precision, decimal_separator, thousand_separator, symbol} = currency
|
let { precision, decimal_separator, thousand_separator, symbol } = currency
|
||||||
|
|
||||||
try {
|
try {
|
||||||
precision = Math.abs(precision)
|
precision = Math.abs(precision)
|
||||||
@ -52,25 +57,44 @@ export default {
|
|||||||
|
|
||||||
const negativeSign = amount < 0 ? '-' : ''
|
const negativeSign = amount < 0 ? '-' : ''
|
||||||
|
|
||||||
let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(precision)).toString()
|
let i = parseInt(
|
||||||
let j = (i.length > 3) ? i.length % 3 : 0
|
(amount = Math.abs(Number(amount) || 0).toFixed(precision))
|
||||||
|
).toString()
|
||||||
|
let j = i.length > 3 ? i.length % 3 : 0
|
||||||
|
|
||||||
let moneySymbol = `<span style="font-family: sans-serif">${symbol}</span>`
|
let moneySymbol = `<span style="font-family: sans-serif">${symbol}</span>`
|
||||||
|
|
||||||
return moneySymbol + ' ' + negativeSign + (j ? i.substr(0, j) + thousand_separator : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand_separator) + (precision ? decimal_separator + Math.abs(amount - i).toFixed(precision).slice(2) : '')
|
return (
|
||||||
|
moneySymbol +
|
||||||
|
' ' +
|
||||||
|
negativeSign +
|
||||||
|
(j ? i.substr(0, j) + thousand_separator : '') +
|
||||||
|
i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand_separator) +
|
||||||
|
(precision
|
||||||
|
? decimal_separator +
|
||||||
|
Math.abs(amount - i)
|
||||||
|
.toFixed(precision)
|
||||||
|
.slice(2)
|
||||||
|
: '')
|
||||||
|
)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
formatGraphMoney (amount, currency = 0) {
|
formatGraphMoney(amount, currency = 0) {
|
||||||
if (!currency) {
|
if (!currency) {
|
||||||
currency = {precision: 2, thousand_separator: ',', decimal_separator: '.', symbol: '$'}
|
currency = {
|
||||||
|
precision: 2,
|
||||||
|
thousand_separator: ',',
|
||||||
|
decimal_separator: '.',
|
||||||
|
symbol: '$',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
amount = amount / 100
|
amount = amount / 100
|
||||||
|
|
||||||
let {precision, decimal_separator, thousand_separator, symbol} = currency
|
let { precision, decimal_separator, thousand_separator, symbol } = currency
|
||||||
|
|
||||||
try {
|
try {
|
||||||
precision = Math.abs(precision)
|
precision = Math.abs(precision)
|
||||||
@ -78,25 +102,76 @@ export default {
|
|||||||
|
|
||||||
const negativeSign = amount < 0 ? '-' : ''
|
const negativeSign = amount < 0 ? '-' : ''
|
||||||
|
|
||||||
let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(precision)).toString()
|
let i = parseInt(
|
||||||
let j = (i.length > 3) ? i.length % 3 : 0
|
(amount = Math.abs(Number(amount) || 0).toFixed(precision))
|
||||||
|
).toString()
|
||||||
|
let j = i.length > 3 ? i.length % 3 : 0
|
||||||
|
|
||||||
let moneySymbol = `${symbol}`
|
let moneySymbol = `${symbol}`
|
||||||
|
|
||||||
return moneySymbol + ' ' + negativeSign + (j ? i.substr(0, j) + thousand_separator : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand_separator) + (precision ? decimal_separator + Math.abs(amount - i).toFixed(precision).slice(2) : '')
|
return (
|
||||||
|
moneySymbol +
|
||||||
|
' ' +
|
||||||
|
negativeSign +
|
||||||
|
(j ? i.substr(0, j) + thousand_separator : '') +
|
||||||
|
i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand_separator) +
|
||||||
|
(precision
|
||||||
|
? decimal_separator +
|
||||||
|
Math.abs(amount - i)
|
||||||
|
.toFixed(precision)
|
||||||
|
.slice(2)
|
||||||
|
: '')
|
||||||
|
)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
checkValidUrl (url) {
|
checkValidUrl(url) {
|
||||||
let pattern = new RegExp('^(https?:\\/\\/)?' + // protocol
|
let pattern = new RegExp(
|
||||||
|
'^(https?:\\/\\/)?' + // protocol
|
||||||
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
|
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
|
||||||
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
|
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
|
||||||
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
|
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
|
||||||
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
|
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
|
||||||
'(\\#[-a-z\\d_]*)?$', 'i') // fragment locator
|
'(\\#[-a-z\\d_]*)?$',
|
||||||
|
'i'
|
||||||
|
) // fragment locator
|
||||||
|
|
||||||
return !!pattern.test(url)
|
return !!pattern.test(url)
|
||||||
|
},
|
||||||
|
|
||||||
|
fallbackCopyTextToClipboard(text) {
|
||||||
|
var textArea = document.createElement('textarea')
|
||||||
|
textArea.value = text
|
||||||
|
// Avoid scrolling to bottom
|
||||||
|
textArea.style.top = '0'
|
||||||
|
textArea.style.left = '0'
|
||||||
|
textArea.style.position = 'fixed'
|
||||||
|
document.body.appendChild(textArea)
|
||||||
|
textArea.focus()
|
||||||
|
textArea.select()
|
||||||
|
try {
|
||||||
|
var successful = document.execCommand('copy')
|
||||||
|
var msg = successful ? 'successful' : 'unsuccessful'
|
||||||
|
console.log('Fallback: Copying text command was ' + msg)
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fallback: Oops, unable to copy', err)
|
||||||
}
|
}
|
||||||
|
document.body.removeChild(textArea)
|
||||||
|
},
|
||||||
|
copyTextToClipboard(text) {
|
||||||
|
if (!navigator.clipboard) {
|
||||||
|
this.fallbackCopyTextToClipboard(text)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigator.clipboard.writeText(text).then(
|
||||||
|
function () {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
function (err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"view_pdf": "View PDF",
|
"view_pdf": "View PDF",
|
||||||
|
"copy_pdf_url": "Copy PDF Url",
|
||||||
"download_pdf": "Download PDF",
|
"download_pdf": "Download PDF",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
@ -230,6 +231,7 @@
|
|||||||
"convert_to_invoice": "Convert to Invoice",
|
"convert_to_invoice": "Convert to Invoice",
|
||||||
"mark_as_sent": "Mark as Sent",
|
"mark_as_sent": "Mark as Sent",
|
||||||
"send_estimate": "Send Estimate",
|
"send_estimate": "Send Estimate",
|
||||||
|
"resend_estimate": "Resend Estimate",
|
||||||
"record_payment": "Record Payment",
|
"record_payment": "Record Payment",
|
||||||
"add_estimate": "Add Estimate",
|
"add_estimate": "Add Estimate",
|
||||||
"save_estimate": "Save Estimate",
|
"save_estimate": "Save Estimate",
|
||||||
@ -316,6 +318,7 @@
|
|||||||
"notes": "Notes",
|
"notes": "Notes",
|
||||||
"view": "View",
|
"view": "View",
|
||||||
"send_invoice": "Send Invoice",
|
"send_invoice": "Send Invoice",
|
||||||
|
"resend_invoice": "Resend Invoice",
|
||||||
"invoice_template": "Invoice Template",
|
"invoice_template": "Invoice Template",
|
||||||
"template": "Template",
|
"template": "Template",
|
||||||
"mark_as_sent": "Mark as sent",
|
"mark_as_sent": "Mark as sent",
|
||||||
|
|||||||
@ -4,16 +4,12 @@
|
|||||||
<h3 class="page-title">{{ $t('estimates.title') }}</h3>
|
<h3 class="page-title">{{ $t('estimates.title') }}</h3>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item">
|
<li class="breadcrumb-item">
|
||||||
<router-link
|
<router-link slot="item-title" to="dashboard">
|
||||||
slot="item-title"
|
|
||||||
to="dashboard">
|
|
||||||
{{ $t('general.home') }}
|
{{ $t('general.home') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li class="breadcrumb-item">
|
<li class="breadcrumb-item">
|
||||||
<router-link
|
<router-link slot="item-title" to="#">
|
||||||
slot="item-title"
|
|
||||||
to="#">
|
|
||||||
{{ $tc('estimates.estimate', 2) }}
|
{{ $tc('estimates.estimate', 2) }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
@ -33,11 +29,9 @@
|
|||||||
</base-button>
|
</base-button>
|
||||||
</div>
|
</div>
|
||||||
<router-link slot="item-title" class="col-xs-2" to="estimates/create">
|
<router-link slot="item-title" class="col-xs-2" to="estimates/create">
|
||||||
<base-button
|
<base-button size="large" icon="plus" color="theme">
|
||||||
size="large"
|
{{ $t('estimates.new_estimate') }}</base-button
|
||||||
icon="plus"
|
>
|
||||||
color="theme" >
|
|
||||||
{{ $t('estimates.new_estimate') }}</base-button>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -46,7 +40,7 @@
|
|||||||
<div v-show="showFilters" class="filter-section">
|
<div v-show="showFilters" class="filter-section">
|
||||||
<div class="filter-container">
|
<div class="filter-container">
|
||||||
<div class="filter-customer">
|
<div class="filter-customer">
|
||||||
<label>{{ $tc('customers.customer',1) }} </label>
|
<label>{{ $tc('customers.customer', 1) }} </label>
|
||||||
<base-customer-select
|
<base-customer-select
|
||||||
ref="customerSelect"
|
ref="customerSelect"
|
||||||
@select="onSelectCustomer"
|
@select="onSelectCustomer"
|
||||||
@ -85,21 +79,28 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-estimate">
|
<div class="filter-estimate">
|
||||||
<label>{{ $t('estimates.estimate_number') }}</label>
|
<label>{{ $t('estimates.estimate_number') }}</label>
|
||||||
<base-input
|
<base-input v-model="filters.estimate_number" icon="hashtag" />
|
||||||
v-model="filters.estimate_number"
|
|
||||||
icon="hashtag"/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label class="clear-filter" @click="clearFilter">{{ $t('general.clear_all') }}</label>
|
<label class="clear-filter" @click="clearFilter">{{
|
||||||
|
$t('general.clear_all')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
<div v-cloak v-show="showEmptyScreen" class="col-xs-1 no-data-info" align="center">
|
<div
|
||||||
<moon-walker-icon class="mt-5 mb-4"/>
|
v-cloak
|
||||||
|
v-show="showEmptyScreen"
|
||||||
|
class="col-xs-1 no-data-info"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<moon-walker-icon class="mt-5 mb-4" />
|
||||||
<div class="row" align="center">
|
<div class="row" align="center">
|
||||||
<label class="col title">{{ $t('estimates.no_estimates') }}</label>
|
<label class="col title">{{ $t('estimates.no_estimates') }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="description col mt-1" align="center">{{ $t('estimates.list_of_estimates') }}</label>
|
<label class="description col mt-1" align="center">{{
|
||||||
|
$t('estimates.list_of_estimates')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
<base-button
|
<base-button
|
||||||
@ -116,28 +117,57 @@
|
|||||||
|
|
||||||
<div v-show="!showEmptyScreen" class="table-container">
|
<div v-show="!showEmptyScreen" class="table-container">
|
||||||
<div class="table-actions mt-5">
|
<div class="table-actions mt-5">
|
||||||
<p class="table-stats">{{ $t('general.showing') }}: <b>{{ estimates.length }}</b> {{ $t('general.of') }} <b>{{ totalEstimates }}</b></p>
|
<p class="table-stats">
|
||||||
|
{{ $t('general.showing') }}: <b>{{ estimates.length }}</b>
|
||||||
|
{{ $t('general.of') }} <b>{{ totalEstimates }}</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
<!-- Tabs -->
|
<!-- Tabs -->
|
||||||
<ul class="tabs">
|
<ul class="tabs">
|
||||||
<li class="tab" @click="getStatus('DRAFT')">
|
<li class="tab" @click="getStatus('DRAFT')">
|
||||||
<a :class="['tab-link', {'a-active': filters.status === 'DRAFT'}]" href="#">{{ $t('general.draft') }}</a>
|
<a
|
||||||
|
:class="['tab-link', { 'a-active': filters.status === 'DRAFT' }]"
|
||||||
|
href="#"
|
||||||
|
>{{ $t('general.draft') }}</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="tab" @click="getStatus('SENT')">
|
<li class="tab" @click="getStatus('SENT')">
|
||||||
<a :class="['tab-link', {'a-active': filters.status === 'SENT'}]" href="#" >{{ $t('general.sent') }}</a>
|
<a
|
||||||
|
:class="['tab-link', { 'a-active': filters.status === 'SENT' }]"
|
||||||
|
href="#"
|
||||||
|
>{{ $t('general.sent') }}</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="tab" @click="getStatus('')">
|
<li class="tab" @click="getStatus('')">
|
||||||
<a :class="['tab-link', {'a-active': filters.status === '' || filters.status !== 'DRAFT' && filters.status !== 'SENT'}]" href="#">{{ $t('general.all') }}</a>
|
<a
|
||||||
|
:class="[
|
||||||
|
'tab-link',
|
||||||
|
{
|
||||||
|
'a-active':
|
||||||
|
filters.status === '' ||
|
||||||
|
(filters.status !== 'DRAFT' && filters.status !== 'SENT'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
href="#"
|
||||||
|
>{{ $t('general.all') }}</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<v-dropdown v-if="selectedEstimates.length" :show-arrow="false">
|
<v-dropdown v-if="selectedEstimates.length" :show-arrow="false">
|
||||||
<span slot="activator" href="#" class="table-actions-button dropdown-toggle">
|
<span
|
||||||
|
slot="activator"
|
||||||
|
href="#"
|
||||||
|
class="table-actions-button dropdown-toggle"
|
||||||
|
>
|
||||||
{{ $t('general.actions') }}
|
{{ $t('general.actions') }}
|
||||||
</span>
|
</span>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<div class="dropdown-item" @click="removeMultipleEstimates">
|
<div class="dropdown-item" @click="removeMultipleEstimates">
|
||||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'trash']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.delete') }}
|
{{ $t('general.delete') }}
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
@ -153,8 +183,12 @@
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="custom-control-input"
|
class="custom-control-input"
|
||||||
@change="selectAllEstimates"
|
@change="selectAllEstimates"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
v-show="!isRequestOngoing"
|
||||||
|
for="select-all"
|
||||||
|
class="custom-control-label selectall"
|
||||||
>
|
>
|
||||||
<label v-show="!isRequestOngoing" for="select-all" class="custom-control-label selectall">
|
|
||||||
<span class="select-all-label">{{ $t('general.select_all') }} </span>
|
<span class="select-all-label">{{ $t('general.select_all') }} </span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@ -178,7 +212,7 @@
|
|||||||
:value="row.id"
|
:value="row.id"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="custom-control-input"
|
class="custom-control-input"
|
||||||
>
|
/>
|
||||||
<label :for="row.id" class="custom-control-label" />
|
<label :for="row.id" class="custom-control-label" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -186,30 +220,30 @@
|
|||||||
<table-column
|
<table-column
|
||||||
:label="$t('estimates.date')"
|
:label="$t('estimates.date')"
|
||||||
sort-as="estimate_date"
|
sort-as="estimate_date"
|
||||||
show="formattedEstimateDate" />
|
show="formattedEstimateDate"
|
||||||
|
/>
|
||||||
<table-column
|
<table-column
|
||||||
:label="$t('estimates.customer')"
|
:label="$t('estimates.customer')"
|
||||||
sort-as="name"
|
sort-as="name"
|
||||||
show="name" />
|
show="name"
|
||||||
|
/>
|
||||||
<!-- <table-column
|
<!-- <table-column
|
||||||
:label="$t('estimates.expiry_date')"
|
:label="$t('estimates.expiry_date')"
|
||||||
sort-as="expiry_date"
|
sort-as="expiry_date"
|
||||||
show="formattedExpiryDate" /> -->
|
show="formattedExpiryDate" /> -->
|
||||||
<table-column
|
<table-column :label="$t('estimates.status')" show="status">
|
||||||
:label="$t('estimates.status')"
|
<template slot-scope="row">
|
||||||
show="status" >
|
|
||||||
<template slot-scope="row" >
|
|
||||||
<span> {{ $t('estimates.status') }}</span>
|
<span> {{ $t('estimates.status') }}</span>
|
||||||
<span :class="'est-status-'+row.status.toLowerCase()">{{ row.status }}</span>
|
<span :class="'est-status-' + row.status.toLowerCase()">{{
|
||||||
|
row.status
|
||||||
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</table-column>
|
</table-column>
|
||||||
<table-column
|
<table-column
|
||||||
:label="$tc('estimates.estimate', 1)"
|
:label="$tc('estimates.estimate', 1)"
|
||||||
show="estimate_number"/>
|
show="estimate_number"
|
||||||
<table-column
|
/>
|
||||||
:label="$t('invoices.total')"
|
<table-column :label="$t('invoices.total')" sort-as="total">
|
||||||
sort-as="total"
|
|
||||||
>
|
|
||||||
<template slot-scope="row">
|
<template slot-scope="row">
|
||||||
<span> {{ $t('estimates.total') }}</span>
|
<span> {{ $t('estimates.total') }}</span>
|
||||||
<div v-html="$utils.formatMoney(row.total, row.user.currency)" />
|
<div v-html="$utils.formatMoney(row.total, row.user.currency)" />
|
||||||
@ -227,50 +261,114 @@
|
|||||||
<dot-icon />
|
<dot-icon />
|
||||||
</a>
|
</a>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<router-link :to="{path: `estimates/${row.id}/edit`}" class="dropdown-item">
|
<router-link
|
||||||
<font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon" />
|
:to="{ path: `estimates/${row.id}/edit` }"
|
||||||
|
class="dropdown-item"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'pencil-alt']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.edit') }}
|
{{ $t('general.edit') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<div class="dropdown-item" @click="removeEstimate(row.id)">
|
<div class="dropdown-item" @click="removeEstimate(row.id)">
|
||||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'trash']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.delete') }}
|
{{ $t('general.delete') }}
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<router-link :to="{path: `estimates/${row.id}/view`}" class="dropdown-item">
|
<router-link
|
||||||
|
:to="{ path: `estimates/${row.id}/view` }"
|
||||||
|
class="dropdown-item"
|
||||||
|
>
|
||||||
<font-awesome-icon icon="eye" class="dropdown-item-icon" />
|
<font-awesome-icon icon="eye" class="dropdown-item-icon" />
|
||||||
{{ $t('general.view') }}
|
{{ $t('general.view') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<a class="dropdown-item" href="#/" @click="convertInToinvoice(row.id)">
|
<a
|
||||||
<font-awesome-icon icon="file-alt" class="dropdown-item-icon" />
|
class="dropdown-item"
|
||||||
|
href="#/"
|
||||||
|
@click="convertInToinvoice(row.id)"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
icon="file-alt"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('estimates.convert_to_invoice') }}
|
{{ $t('estimates.convert_to_invoice') }}
|
||||||
</a>
|
</a>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item v-if="row.status !== 'SENT'">
|
<v-dropdown-item v-if="row.status !== 'SENT'">
|
||||||
<a class="dropdown-item" href="#/" @click.self="onMarkAsSent(row.id)">
|
<a
|
||||||
<font-awesome-icon icon="check-circle" class="dropdown-item-icon" />
|
class="dropdown-item"
|
||||||
|
href="#/"
|
||||||
|
@click.self="onMarkAsSent(row.id)"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
icon="check-circle"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('estimates.mark_as_sent') }}
|
{{ $t('estimates.mark_as_sent') }}
|
||||||
</a>
|
</a>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item v-if="row.status !== 'SENT'">
|
<v-dropdown-item v-if="row.status === 'DRAFT'">
|
||||||
<a class="dropdown-item" href="#/" @click.self="sendEstimate(row.id)">
|
<a
|
||||||
<font-awesome-icon icon="paper-plane" class="dropdown-item-icon" />
|
class="dropdown-item"
|
||||||
|
href="#/"
|
||||||
|
@click.self="sendEstimate(row.id)"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
icon="paper-plane"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('estimates.send_estimate') }}
|
{{ $t('estimates.send_estimate') }}
|
||||||
</a>
|
</a>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
|
<!-- resend estimte -->
|
||||||
|
<v-dropdown-item
|
||||||
|
v-if="row.status == 'SENT' || row.status == 'VIEWED'"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#/"
|
||||||
|
@click.self="sendEstimate(row.id)"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
icon="paper-plane"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
|
{{ $t('estimates.resend_estimate') }}
|
||||||
|
</a>
|
||||||
|
</v-dropdown-item>
|
||||||
|
<!-- -->
|
||||||
<v-dropdown-item v-if="row.status !== 'ACCEPTED'">
|
<v-dropdown-item v-if="row.status !== 'ACCEPTED'">
|
||||||
<a class="dropdown-item" href="#/" @click.self="onMarkAsAccepted(row.id)">
|
<a
|
||||||
<font-awesome-icon icon="check-circle" class="dropdown-item-icon" />
|
class="dropdown-item"
|
||||||
|
href="#/"
|
||||||
|
@click.self="onMarkAsAccepted(row.id)"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
icon="check-circle"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('estimates.mark_as_accepted') }}
|
{{ $t('estimates.mark_as_accepted') }}
|
||||||
</a>
|
</a>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item v-if="row.status !== 'REJECTED'">
|
<v-dropdown-item v-if="row.status !== 'REJECTED'">
|
||||||
<a class="dropdown-item" href="#/" @click.self="onMarkAsRejected(row.id)">
|
<a
|
||||||
<font-awesome-icon icon="times-circle" class="dropdown-item-icon" />
|
class="dropdown-item"
|
||||||
|
href="#/"
|
||||||
|
@click.self="onMarkAsRejected(row.id)"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
icon="times-circle"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('estimates.mark_as_rejected') }}
|
{{ $t('estimates.mark_as_rejected') }}
|
||||||
</a>
|
</a>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="estimate" class="main-content estimate-view-page">
|
<div v-if="estimate" class="main-content estimate-view-page">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h3 class="page-title"> {{ estimate.estimate_number }}</h3>
|
<h3 class="page-title">{{ estimate.estimate_number }}</h3>
|
||||||
<div class="page-actions row">
|
<div class="page-actions row">
|
||||||
<div class="col-xs-2 mr-3">
|
<div class="col-xs-2 mr-3">
|
||||||
<base-button
|
<base-button
|
||||||
@ -26,19 +26,42 @@
|
|||||||
{{ $t('estimates.send_estimate') }}
|
{{ $t('estimates.send_estimate') }}
|
||||||
</base-button>
|
</base-button>
|
||||||
</div>
|
</div>
|
||||||
<v-dropdown :close-on-select="false" align="left" class="filter-container">
|
<v-dropdown
|
||||||
|
:close-on-select="true"
|
||||||
|
align="left"
|
||||||
|
class="filter-container"
|
||||||
|
>
|
||||||
<a slot="activator" href="#">
|
<a slot="activator" href="#">
|
||||||
<base-button color="theme">
|
<base-button color="theme">
|
||||||
<font-awesome-icon icon="ellipsis-h" />
|
<font-awesome-icon icon="ellipsis-h" />
|
||||||
</base-button>
|
</base-button>
|
||||||
</a>
|
</a>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<router-link :to="{path: `/admin/estimates/${$route.params.id}/edit`}" class="dropdown-item">
|
<div class="dropdown-item" @click="copyPdfUrl()">
|
||||||
<font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon"/>
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'link']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
|
{{ $t('general.copy_pdf_url') }}
|
||||||
|
</div>
|
||||||
|
<router-link
|
||||||
|
:to="{ path: `/admin/estimates/${$route.params.id}/edit` }"
|
||||||
|
class="dropdown-item"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'pencil-alt']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.edit') }}
|
{{ $t('general.edit') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="dropdown-item" @click="removeEstimate($route.params.id)">
|
<div
|
||||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
class="dropdown-item"
|
||||||
|
@click="removeEstimate($route.params.id)"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'trash']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.delete') }}
|
{{ $t('general.delete') }}
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
@ -57,14 +80,18 @@
|
|||||||
align-icon="right"
|
align-icon="right"
|
||||||
@input="onSearched()"
|
@input="onSearched()"
|
||||||
/>
|
/>
|
||||||
<div
|
<div class="btn-group ml-3" role="group" aria-label="First group">
|
||||||
class="btn-group ml-3"
|
<v-dropdown
|
||||||
role="group"
|
:close-on-select="false"
|
||||||
aria-label="First group"
|
align="left"
|
||||||
|
class="filter-container"
|
||||||
>
|
>
|
||||||
<v-dropdown :close-on-select="false" align="left" class="filter-container">
|
|
||||||
<a slot="activator" href="#">
|
<a slot="activator" href="#">
|
||||||
<base-button class="inv-button inv-filter-fields-btn" color="default" size="medium">
|
<base-button
|
||||||
|
class="inv-button inv-filter-fields-btn"
|
||||||
|
color="default"
|
||||||
|
size="medium"
|
||||||
|
>
|
||||||
<font-awesome-icon icon="filter" />
|
<font-awesome-icon icon="filter" />
|
||||||
</base-button>
|
</base-button>
|
||||||
</a>
|
</a>
|
||||||
@ -80,8 +107,10 @@
|
|||||||
class="inv-radio"
|
class="inv-radio"
|
||||||
value="estimate_date"
|
value="estimate_date"
|
||||||
@change="onSearched"
|
@change="onSearched"
|
||||||
>
|
/>
|
||||||
<label class="inv-label" for="filter_estimate_date">{{ $t('reports.estimates.estimate_date') }}</label>
|
<label class="inv-label" for="filter_estimate_date">{{
|
||||||
|
$t('reports.estimates.estimate_date')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-items">
|
<div class="filter-items">
|
||||||
<input
|
<input
|
||||||
@ -92,8 +121,10 @@
|
|||||||
class="inv-radio"
|
class="inv-radio"
|
||||||
value="expiry_date"
|
value="expiry_date"
|
||||||
@change="onSearched"
|
@change="onSearched"
|
||||||
>
|
/>
|
||||||
<label class="inv-label" for="filter_due_date">{{ $t('estimates.due_date') }}</label>
|
<label class="inv-label" for="filter_due_date">{{
|
||||||
|
$t('estimates.due_date')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-items">
|
<div class="filter-items">
|
||||||
<input
|
<input
|
||||||
@ -104,11 +135,19 @@
|
|||||||
class="inv-radio"
|
class="inv-radio"
|
||||||
value="estimate_number"
|
value="estimate_number"
|
||||||
@change="onSearched"
|
@change="onSearched"
|
||||||
>
|
/>
|
||||||
<label class="inv-label" for="filter_estimate_number">{{ $t('estimates.estimate_number') }}</label>
|
<label class="inv-label" for="filter_estimate_number">{{
|
||||||
|
$t('estimates.estimate_number')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown>
|
</v-dropdown>
|
||||||
<base-button v-tooltip.top-center="{ content: getOrderName }" class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData">
|
<base-button
|
||||||
|
v-tooltip.top-center="{ content: getOrderName }"
|
||||||
|
class="inv-button inv-filter-sorting-btn"
|
||||||
|
color="default"
|
||||||
|
size="medium"
|
||||||
|
@click="sortData"
|
||||||
|
>
|
||||||
<font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" />
|
<font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" />
|
||||||
<font-awesome-icon v-else icon="sort-amount-down" />
|
<font-awesome-icon v-else icon="sort-amount-down" />
|
||||||
</base-button>
|
</base-button>
|
||||||
@ -116,7 +155,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="side-content">
|
<div class="side-content">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="(estimate,index) in estimates"
|
v-for="(estimate, index) in estimates"
|
||||||
:to="`/admin/estimates/${estimate.id}/view`"
|
:to="`/admin/estimates/${estimate.id}/view`"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="side-estimate"
|
class="side-estimate"
|
||||||
@ -124,10 +163,20 @@
|
|||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="inv-name">{{ estimate.user.name }}</div>
|
<div class="inv-name">{{ estimate.user.name }}</div>
|
||||||
<div class="inv-number">{{ estimate.estimate_number }}</div>
|
<div class="inv-number">{{ estimate.estimate_number }}</div>
|
||||||
<div :class="'est-status-'+estimate.status.toLowerCase()" class="inv-status">{{ estimate.status }}</div>
|
<div
|
||||||
|
:class="'est-status-' + estimate.status.toLowerCase()"
|
||||||
|
class="inv-status"
|
||||||
|
>
|
||||||
|
{{ estimate.status }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="inv-amount" v-html="$utils.formatMoney(estimate.total, estimate.user.currency)" />
|
<div
|
||||||
|
class="inv-amount"
|
||||||
|
v-html="
|
||||||
|
$utils.formatMoney(estimate.total, estimate.user.currency)
|
||||||
|
"
|
||||||
|
/>
|
||||||
<div class="inv-date">{{ estimate.formattedEstimateDate }}</div>
|
<div class="inv-date">{{ estimate.formattedEstimateDate }}</div>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
@ -137,7 +186,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="estimate-view-page-container">
|
<div class="estimate-view-page-container">
|
||||||
<iframe :src="`${shareableLink}`" class="frame-style"/>
|
<iframe :src="`${shareableLink}`" class="frame-style" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -289,6 +338,13 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
copyPdfUrl () {
|
||||||
|
let pdfUrl = `${window.location.origin}/estimates/pdf/${this.estimate.unique_hash}`
|
||||||
|
|
||||||
|
let response = this.$utils.copyTextToClipboard(pdfUrl)
|
||||||
|
|
||||||
|
window.toastr['success'](this.$tc('Copied PDF url to clipboard!'))
|
||||||
|
},
|
||||||
async removeEstimate (id) {
|
async removeEstimate (id) {
|
||||||
window.swal({
|
window.swal({
|
||||||
title: 'Deleted',
|
title: 'Deleted',
|
||||||
|
|||||||
@ -1,19 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="invoice-index-page invoices main-content">
|
<div class="invoice-index-page invoices main-content">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h3 class="page-title"> {{ $t('invoices.title') }}</h3>
|
<h3 class="page-title">{{ $t('invoices.title') }}</h3>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item">
|
<li class="breadcrumb-item">
|
||||||
<router-link
|
<router-link slot="item-title" to="dashboard">
|
||||||
slot="item-title"
|
|
||||||
to="dashboard">
|
|
||||||
{{ $t('general.home') }}
|
{{ $t('general.home') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li class="breadcrumb-item">
|
<li class="breadcrumb-item">
|
||||||
<router-link
|
<router-link slot="item-title" to="#">
|
||||||
slot="item-title"
|
|
||||||
to="#">
|
|
||||||
{{ $tc('invoices.invoice', 2) }}
|
{{ $tc('invoices.invoice', 2) }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
@ -32,7 +28,11 @@
|
|||||||
{{ $t('general.filter') }}
|
{{ $t('general.filter') }}
|
||||||
</base-button>
|
</base-button>
|
||||||
</div>
|
</div>
|
||||||
<router-link slot="item-title" class="col-xs-2" to="/admin/invoices/create">
|
<router-link
|
||||||
|
slot="item-title"
|
||||||
|
class="col-xs-2"
|
||||||
|
to="/admin/invoices/create"
|
||||||
|
>
|
||||||
<base-button size="large" icon="plus" color="theme">
|
<base-button size="large" icon="plus" color="theme">
|
||||||
{{ $t('invoices.new_invoice') }}
|
{{ $t('invoices.new_invoice') }}
|
||||||
</base-button>
|
</base-button>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
<div v-show="showFilters" class="filter-section">
|
<div v-show="showFilters" class="filter-section">
|
||||||
<div class="filter-container">
|
<div class="filter-container">
|
||||||
<div class="filter-customer">
|
<div class="filter-customer">
|
||||||
<label>{{ $tc('customers.customer',1) }} </label>
|
<label>{{ $tc('customers.customer', 1) }} </label>
|
||||||
<base-customer-select
|
<base-customer-select
|
||||||
ref="customerSelect"
|
ref="customerSelect"
|
||||||
@select="onSelectCustomer"
|
@select="onSelectCustomer"
|
||||||
@ -88,22 +88,29 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-invoice">
|
<div class="filter-invoice">
|
||||||
<label>{{ $t('invoices.invoice_number') }}</label>
|
<label>{{ $t('invoices.invoice_number') }}</label>
|
||||||
<base-input
|
<base-input v-model="filters.invoice_number" icon="hashtag" />
|
||||||
v-model="filters.invoice_number"
|
|
||||||
icon="hashtag"/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label class="clear-filter" @click="clearFilter">{{ $t('general.clear_all') }}</label>
|
<label class="clear-filter" @click="clearFilter">{{
|
||||||
|
$t('general.clear_all')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
||||||
<div v-cloak v-show="showEmptyScreen" class="col-xs-1 no-data-info" align="center">
|
<div
|
||||||
<moon-walker-icon class="mt-5 mb-4"/>
|
v-cloak
|
||||||
|
v-show="showEmptyScreen"
|
||||||
|
class="col-xs-1 no-data-info"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<moon-walker-icon class="mt-5 mb-4" />
|
||||||
<div class="row" align="center">
|
<div class="row" align="center">
|
||||||
<label class="col title">{{ $t('invoices.no_invoices') }}</label>
|
<label class="col title">{{ $t('invoices.no_invoices') }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="description col mt-1" align="center">{{ $t('invoices.list_of_invoices') }}</label>
|
<label class="description col mt-1" align="center">{{
|
||||||
|
$t('invoices.list_of_invoices')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
<base-button
|
<base-button
|
||||||
@ -120,28 +127,65 @@
|
|||||||
|
|
||||||
<div v-show="!showEmptyScreen" class="table-container">
|
<div v-show="!showEmptyScreen" class="table-container">
|
||||||
<div class="table-actions mt-5">
|
<div class="table-actions mt-5">
|
||||||
<p class="table-stats">{{ $t('general.showing') }}: <b>{{ invoices.length }}</b> {{ $t('general.of') }} <b>{{ totalInvoices }}</b></p>
|
<p class="table-stats">
|
||||||
|
{{ $t('general.showing') }}: <b>{{ invoices.length }}</b>
|
||||||
|
{{ $t('general.of') }} <b>{{ totalInvoices }}</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
<!-- Tabs -->
|
<!-- Tabs -->
|
||||||
<ul class="tabs">
|
<ul class="tabs">
|
||||||
<li class="tab" @click="getStatus('UNPAID')">
|
<li class="tab" @click="getStatus('UNPAID')">
|
||||||
<a :class="['tab-link', {'a-active': filters.status.value === 'UNPAID'}]" href="#" >{{ $t('general.due') }}</a>
|
<a
|
||||||
|
:class="[
|
||||||
|
'tab-link',
|
||||||
|
{ 'a-active': filters.status.value === 'UNPAID' },
|
||||||
|
]"
|
||||||
|
href="#"
|
||||||
|
>{{ $t('general.due') }}</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="tab" @click="getStatus('DRAFT')">
|
<li class="tab" @click="getStatus('DRAFT')">
|
||||||
<a :class="['tab-link', {'a-active': filters.status.value === 'DRAFT'}]" href="#">{{ $t('general.draft') }}</a>
|
<a
|
||||||
|
:class="[
|
||||||
|
'tab-link',
|
||||||
|
{ 'a-active': filters.status.value === 'DRAFT' },
|
||||||
|
]"
|
||||||
|
href="#"
|
||||||
|
>{{ $t('general.draft') }}</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="tab" @click="getStatus('')">
|
<li class="tab" @click="getStatus('')">
|
||||||
<a :class="['tab-link', {'a-active': filters.status.value === '' || filters.status.value === null || filters.status.value !== 'DRAFT' && filters.status.value !== 'UNPAID'}]" href="#">{{ $t('general.all') }}</a>
|
<a
|
||||||
|
:class="[
|
||||||
|
'tab-link',
|
||||||
|
{
|
||||||
|
'a-active':
|
||||||
|
filters.status.value === '' ||
|
||||||
|
filters.status.value === null ||
|
||||||
|
(filters.status.value !== 'DRAFT' &&
|
||||||
|
filters.status.value !== 'UNPAID'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
href="#"
|
||||||
|
>{{ $t('general.all') }}</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<v-dropdown v-if="selectedInvoices.length" :show-arrow="false">
|
<v-dropdown v-if="selectedInvoices.length" :show-arrow="false">
|
||||||
<span slot="activator" href="#" class="table-actions-button dropdown-toggle">
|
<span
|
||||||
|
slot="activator"
|
||||||
|
href="#"
|
||||||
|
class="table-actions-button dropdown-toggle"
|
||||||
|
>
|
||||||
{{ $t('general.actions') }}
|
{{ $t('general.actions') }}
|
||||||
</span>
|
</span>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<div class="dropdown-item" @click="removeMultipleInvoices">
|
<div class="dropdown-item" @click="removeMultipleInvoices">
|
||||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'trash']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.delete') }}
|
{{ $t('general.delete') }}
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
@ -155,8 +199,12 @@
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="custom-control-input"
|
class="custom-control-input"
|
||||||
@change="selectAllInvoices"
|
@change="selectAllInvoices"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
v-show="!isRequestOngoing"
|
||||||
|
for="select-all"
|
||||||
|
class="custom-control-label selectall"
|
||||||
>
|
>
|
||||||
<label v-show="!isRequestOngoing" for="select-all" class="custom-control-label selectall">
|
|
||||||
<span class="select-all-label">{{ $t('general.select_all') }} </span>
|
<span class="select-all-label">{{ $t('general.select_all') }} </span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@ -180,8 +228,8 @@
|
|||||||
:value="row.id"
|
:value="row.id"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="custom-control-input"
|
class="custom-control-input"
|
||||||
>
|
/>
|
||||||
<label :for="row.id" class="custom-control-label"/>
|
<label :for="row.id" class="custom-control-label" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</table-column>
|
</table-column>
|
||||||
@ -195,35 +243,33 @@
|
|||||||
width="20%"
|
width="20%"
|
||||||
show="name"
|
show="name"
|
||||||
/>
|
/>
|
||||||
<table-column
|
<table-column :label="$t('invoices.status')" sort-as="status">
|
||||||
:label="$t('invoices.status')"
|
<template slot-scope="row">
|
||||||
sort-as="status"
|
|
||||||
>
|
|
||||||
<template slot-scope="row" >
|
|
||||||
<span> {{ $t('invoices.status') }}</span>
|
<span> {{ $t('invoices.status') }}</span>
|
||||||
<span :class="'inv-status-'+row.status.toLowerCase()">{{ (row.status != 'PARTIALLY_PAID')? row.status : row.status.replace('_', ' ') }}</span>
|
<span :class="'inv-status-' + row.status.toLowerCase()">{{
|
||||||
|
row.status != 'PARTIALLY_PAID'
|
||||||
|
? row.status
|
||||||
|
: row.status.replace('_', ' ')
|
||||||
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</table-column>
|
</table-column>
|
||||||
<table-column
|
<table-column :label="$t('invoices.paid_status')" sort-as="paid_status">
|
||||||
:label="$t('invoices.paid_status')"
|
|
||||||
sort-as="paid_status"
|
|
||||||
>
|
|
||||||
<template slot-scope="row">
|
<template slot-scope="row">
|
||||||
<span>{{ $t('invoices.paid_status') }}</span>
|
<span>{{ $t('invoices.paid_status') }}</span>
|
||||||
<span :class="'inv-status-'+row.paid_status.toLowerCase()">{{ (row.paid_status != 'PARTIALLY_PAID')? row.paid_status : row.paid_status.replace('_', ' ') }}</span>
|
<span :class="'inv-status-' + row.paid_status.toLowerCase()">{{
|
||||||
|
row.paid_status != 'PARTIALLY_PAID'
|
||||||
|
? row.paid_status
|
||||||
|
: row.paid_status.replace('_', ' ')
|
||||||
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</table-column>
|
</table-column>
|
||||||
<table-column
|
<table-column :label="$t('invoices.number')" show="invoice_number" />
|
||||||
:label="$t('invoices.number')"
|
<table-column :label="$t('invoices.amount_due')" sort-as="due_amount">
|
||||||
show="invoice_number"
|
|
||||||
/>
|
|
||||||
<table-column
|
|
||||||
:label="$t('invoices.amount_due')"
|
|
||||||
sort-as="due_amount"
|
|
||||||
>
|
|
||||||
<template slot-scope="row">
|
<template slot-scope="row">
|
||||||
<span>{{ $t('invoices.amount_due') }}</span>
|
<span>{{ $t('invoices.amount_due') }}</span>
|
||||||
<div v-html="$utils.formatMoney(row.due_amount, row.user.currency)"/>
|
<div
|
||||||
|
v-html="$utils.formatMoney(row.due_amount, row.user.currency)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</table-column>
|
</table-column>
|
||||||
<table-column
|
<table-column
|
||||||
@ -238,42 +284,91 @@
|
|||||||
<dot-icon />
|
<dot-icon />
|
||||||
</a>
|
</a>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<router-link :to="{path: `invoices/${row.id}/edit`}" class="dropdown-item">
|
<router-link
|
||||||
<font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon"/>
|
:to="{ path: `invoices/${row.id}/edit` }"
|
||||||
|
class="dropdown-item"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'pencil-alt']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.edit') }}
|
{{ $t('general.edit') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link :to="{path: `invoices/${row.id}/view`}" class="dropdown-item">
|
<router-link
|
||||||
|
:to="{ path: `invoices/${row.id}/view` }"
|
||||||
|
class="dropdown-item"
|
||||||
|
>
|
||||||
<font-awesome-icon icon="eye" class="dropdown-item-icon" />
|
<font-awesome-icon icon="eye" class="dropdown-item-icon" />
|
||||||
{{ $t('invoices.view') }}
|
{{ $t('invoices.view') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item v-if="row.status == 'DRAFT'">
|
<v-dropdown-item v-if="row.status == 'DRAFT'">
|
||||||
<a class="dropdown-item" href="#/" @click="sendInvoice(row.id)" >
|
<a class="dropdown-item" href="#/" @click="sendInvoice(row.id)">
|
||||||
<font-awesome-icon icon="paper-plane" class="dropdown-item-icon" />
|
<font-awesome-icon
|
||||||
|
icon="paper-plane"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('invoices.send_invoice') }}
|
{{ $t('invoices.send_invoice') }}
|
||||||
</a>
|
</a>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
|
<v-dropdown-item
|
||||||
|
v-if="row.status === 'SENT' || row.status === 'VIEWED'"
|
||||||
|
>
|
||||||
|
<a class="dropdown-item" href="#/" @click="sendInvoice(row.id)">
|
||||||
|
<font-awesome-icon
|
||||||
|
icon="paper-plane"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
|
{{ $t('invoices.resend_invoice') }}
|
||||||
|
</a>
|
||||||
|
</v-dropdown-item>
|
||||||
<v-dropdown-item v-if="row.status == 'DRAFT'">
|
<v-dropdown-item v-if="row.status == 'DRAFT'">
|
||||||
<a class="dropdown-item" href="#/" @click="markInvoiceAsSent(row.id)">
|
<a
|
||||||
<font-awesome-icon icon="check-circle" class="dropdown-item-icon" />
|
class="dropdown-item"
|
||||||
|
href="#/"
|
||||||
|
@click="markInvoiceAsSent(row.id)"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
icon="check-circle"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('invoices.mark_as_sent') }}
|
{{ $t('invoices.mark_as_sent') }}
|
||||||
</a>
|
</a>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item v-if="row.status === 'SENT' || row.status === 'VIEWED' || row.status === 'OVERDUE'">
|
<v-dropdown-item
|
||||||
<router-link :to="`/admin/payments/${row.id}/create`" class="dropdown-item">
|
v-if="
|
||||||
<font-awesome-icon :icon="['fas', 'credit-card']" class="dropdown-item-icon"/>
|
row.status === 'SENT' ||
|
||||||
|
row.status === 'VIEWED' ||
|
||||||
|
row.status === 'OVERDUE'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="`/admin/payments/${row.id}/create`"
|
||||||
|
class="dropdown-item"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'credit-card']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('payments.record_payment') }}
|
{{ $t('payments.record_payment') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<a class="dropdown-item" href="#/" @click="onCloneInvoice(row.id)">
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#/"
|
||||||
|
@click="onCloneInvoice(row.id)"
|
||||||
|
>
|
||||||
<font-awesome-icon icon="copy" class="dropdown-item-icon" />
|
<font-awesome-icon icon="copy" class="dropdown-item-icon" />
|
||||||
{{ $t('invoices.clone_invoice') }}
|
{{ $t('invoices.clone_invoice') }}
|
||||||
</a>
|
</a>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<div class="dropdown-item" @click="removeInvoice(row.id)">
|
<div class="dropdown-item" @click="removeInvoice(row.id)">
|
||||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'trash']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.delete') }}
|
{{ $t('general.delete') }}
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="invoice" class="main-content invoice-view-page">
|
<div v-if="invoice" class="main-content invoice-view-page">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h3 class="page-title"> {{ invoice.invoice_number }}</h3>
|
<h3 class="page-title">{{ invoice.invoice_number }}</h3>
|
||||||
<div class="page-actions row">
|
<div class="page-actions row">
|
||||||
<div class="col-xs-2 mr-3">
|
<div class="col-xs-2 mr-3">
|
||||||
<base-button
|
<base-button
|
||||||
@ -24,26 +24,47 @@
|
|||||||
>
|
>
|
||||||
{{ $t('invoices.send_invoice') }}
|
{{ $t('invoices.send_invoice') }}
|
||||||
</base-button>
|
</base-button>
|
||||||
<router-link v-if="invoice.status === 'SENT'" :to="`/admin/payments/${$route.params.id}/create`">
|
<router-link
|
||||||
<base-button
|
v-if="invoice.status === 'SENT'"
|
||||||
color="theme"
|
:to="`/admin/payments/${$route.params.id}/create`"
|
||||||
>
|
>
|
||||||
|
<base-button color="theme">
|
||||||
{{ $t('payments.record_payment') }}
|
{{ $t('payments.record_payment') }}
|
||||||
</base-button>
|
</base-button>
|
||||||
</router-link>
|
</router-link>
|
||||||
<v-dropdown :close-on-select="false" align="left" class="filter-container">
|
<v-dropdown
|
||||||
|
:close-on-select="true"
|
||||||
|
align="left"
|
||||||
|
class="filter-container"
|
||||||
|
>
|
||||||
<a slot="activator" href="#">
|
<a slot="activator" href="#">
|
||||||
<base-button color="theme">
|
<base-button color="theme">
|
||||||
<font-awesome-icon icon="ellipsis-h" />
|
<font-awesome-icon icon="ellipsis-h" />
|
||||||
</base-button>
|
</base-button>
|
||||||
</a>
|
</a>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<router-link :to="{path: `/admin/invoices/${$route.params.id}/edit`}" class="dropdown-item">
|
<div class="dropdown-item" @click="copyPdfUrl">
|
||||||
<font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon"/>
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'link']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
|
{{ $t('general.copy_pdf_url') }}
|
||||||
|
</div>
|
||||||
|
<router-link
|
||||||
|
:to="{ path: `/admin/invoices/${$route.params.id}/edit` }"
|
||||||
|
class="dropdown-item"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'pencil-alt']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.edit') }}
|
{{ $t('general.edit') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="dropdown-item" @click="removeInvoice($route.params.id)">
|
<div class="dropdown-item" @click="removeInvoice($route.params.id)">
|
||||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'trash']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.delete') }}
|
{{ $t('general.delete') }}
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
@ -61,14 +82,18 @@
|
|||||||
align-icon="right"
|
align-icon="right"
|
||||||
@input="onSearch"
|
@input="onSearch"
|
||||||
/>
|
/>
|
||||||
<div
|
<div class="btn-group ml-3" role="group" aria-label="First group">
|
||||||
class="btn-group ml-3"
|
<v-dropdown
|
||||||
role="group"
|
:close-on-select="false"
|
||||||
aria-label="First group"
|
align="left"
|
||||||
|
class="filter-container"
|
||||||
>
|
>
|
||||||
<v-dropdown :close-on-select="false" align="left" class="filter-container">
|
|
||||||
<a slot="activator" href="#">
|
<a slot="activator" href="#">
|
||||||
<base-button class="inv-button inv-filter-fields-btn" color="default" size="medium">
|
<base-button
|
||||||
|
class="inv-button inv-filter-fields-btn"
|
||||||
|
color="default"
|
||||||
|
size="medium"
|
||||||
|
>
|
||||||
<font-awesome-icon icon="filter" />
|
<font-awesome-icon icon="filter" />
|
||||||
</base-button>
|
</base-button>
|
||||||
</a>
|
</a>
|
||||||
@ -84,8 +109,10 @@
|
|||||||
class="inv-radio"
|
class="inv-radio"
|
||||||
value="invoice_date"
|
value="invoice_date"
|
||||||
@change="onSearch"
|
@change="onSearch"
|
||||||
>
|
/>
|
||||||
<label class="inv-label" for="filter_invoice_date">{{ $t('invoices.invoice_date') }}</label>
|
<label class="inv-label" for="filter_invoice_date">{{
|
||||||
|
$t('invoices.invoice_date')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-items">
|
<div class="filter-items">
|
||||||
<input
|
<input
|
||||||
@ -96,8 +123,10 @@
|
|||||||
class="inv-radio"
|
class="inv-radio"
|
||||||
value="due_date"
|
value="due_date"
|
||||||
@change="onSearch"
|
@change="onSearch"
|
||||||
>
|
/>
|
||||||
<label class="inv-label" for="filter_due_date">{{ $t('invoices.due_date') }}</label>
|
<label class="inv-label" for="filter_due_date">{{
|
||||||
|
$t('invoices.due_date')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-items">
|
<div class="filter-items">
|
||||||
<input
|
<input
|
||||||
@ -108,11 +137,19 @@
|
|||||||
class="inv-radio"
|
class="inv-radio"
|
||||||
value="invoice_number"
|
value="invoice_number"
|
||||||
@change="onSearch"
|
@change="onSearch"
|
||||||
>
|
/>
|
||||||
<label class="inv-label" for="filter_invoice_number">{{ $t('invoices.invoice_number') }}</label>
|
<label class="inv-label" for="filter_invoice_number">{{
|
||||||
|
$t('invoices.invoice_number')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown>
|
</v-dropdown>
|
||||||
<base-button v-tooltip.top-center="{ content: getOrderName }" class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData">
|
<base-button
|
||||||
|
v-tooltip.top-center="{ content: getOrderName }"
|
||||||
|
class="inv-button inv-filter-sorting-btn"
|
||||||
|
color="default"
|
||||||
|
size="medium"
|
||||||
|
@click="sortData"
|
||||||
|
>
|
||||||
<font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" />
|
<font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" />
|
||||||
<font-awesome-icon v-else icon="sort-amount-down" />
|
<font-awesome-icon v-else icon="sort-amount-down" />
|
||||||
</base-button>
|
</base-button>
|
||||||
@ -121,7 +158,7 @@
|
|||||||
<base-loader v-if="isSearching" />
|
<base-loader v-if="isSearching" />
|
||||||
<div v-else class="side-content">
|
<div v-else class="side-content">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="(invoice,index) in invoices"
|
v-for="(invoice, index) in invoices"
|
||||||
:to="`/admin/invoices/${invoice.id}/view`"
|
:to="`/admin/invoices/${invoice.id}/view`"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="side-invoice"
|
class="side-invoice"
|
||||||
@ -129,10 +166,20 @@
|
|||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="inv-name">{{ invoice.user.name }}</div>
|
<div class="inv-name">{{ invoice.user.name }}</div>
|
||||||
<div class="inv-number">{{ invoice.invoice_number }}</div>
|
<div class="inv-number">{{ invoice.invoice_number }}</div>
|
||||||
<div :class="'inv-status-'+invoice.status.toLowerCase()" class="inv-status">{{ invoice.status }}</div>
|
<div
|
||||||
|
:class="'inv-status-' + invoice.status.toLowerCase()"
|
||||||
|
class="inv-status"
|
||||||
|
>
|
||||||
|
{{ invoice.status }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="inv-amount" v-html="$utils.formatMoney(invoice.due_amount, invoice.user.currency)" />
|
<div
|
||||||
|
class="inv-amount"
|
||||||
|
v-html="
|
||||||
|
$utils.formatMoney(invoice.due_amount, invoice.user.currency)
|
||||||
|
"
|
||||||
|
/>
|
||||||
<div class="inv-date">{{ invoice.formattedInvoiceDate }}</div>
|
<div class="inv-date">{{ invoice.formattedInvoiceDate }}</div>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
@ -141,8 +188,8 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="invoice-view-page-container" >
|
<div class="invoice-view-page-container">
|
||||||
<iframe :src="`${shareableLink}`" class="frame-style"/>
|
<iframe :src="`${shareableLink}`" class="frame-style" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -291,6 +338,14 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
copyPdfUrl () {
|
||||||
|
let pdfUrl = `${window.location.origin}/invoices/pdf/${this.invoice.unique_hash}`
|
||||||
|
|
||||||
|
let response = this.$utils.copyTextToClipboard(pdfUrl)
|
||||||
|
|
||||||
|
window.toastr['success'](this.$tc('Copied PDF url to clipboard!'))
|
||||||
|
|
||||||
|
},
|
||||||
async removeInvoice (id) {
|
async removeInvoice (id) {
|
||||||
this.selectInvoice([parseInt(id)])
|
this.selectInvoice([parseInt(id)])
|
||||||
this.id = id
|
this.id = id
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="payment" class="main-content payment-view-page">
|
<div v-if="payment" class="main-content payment-view-page">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h3 class="page-title"> {{ payment.payment_number }}</h3>
|
<h3 class="page-title">{{ payment.payment_number }}</h3>
|
||||||
<div class="page-actions row">
|
<div class="page-actions row">
|
||||||
<base-button
|
<base-button
|
||||||
:loading="isSendingEmail"
|
:loading="isSendingEmail"
|
||||||
@ -11,19 +11,39 @@
|
|||||||
>
|
>
|
||||||
{{ $t('payments.send_payment_receipt') }}
|
{{ $t('payments.send_payment_receipt') }}
|
||||||
</base-button>
|
</base-button>
|
||||||
<v-dropdown :close-on-select="false" align="left" class="filter-container">
|
<v-dropdown
|
||||||
|
:close-on-select="true"
|
||||||
|
align="left"
|
||||||
|
class="filter-container"
|
||||||
|
>
|
||||||
<a slot="activator" href="#">
|
<a slot="activator" href="#">
|
||||||
<base-button color="theme">
|
<base-button color="theme">
|
||||||
<font-awesome-icon icon="ellipsis-h" />
|
<font-awesome-icon icon="ellipsis-h" />
|
||||||
</base-button>
|
</base-button>
|
||||||
</a>
|
</a>
|
||||||
<v-dropdown-item>
|
<v-dropdown-item>
|
||||||
<router-link :to="{path: `/admin/payments/${$route.params.id}/edit`}" class="dropdown-item">
|
<div class="dropdown-item" @click="copyPdfUrl">
|
||||||
<font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon"/>
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'link']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
|
{{ $t('general.copy_pdf_url') }}
|
||||||
|
</div>
|
||||||
|
<router-link
|
||||||
|
:to="{ path: `/admin/payments/${$route.params.id}/edit` }"
|
||||||
|
class="dropdown-item"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'pencil-alt']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.edit') }}
|
{{ $t('general.edit') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="dropdown-item" @click="removePayment($route.params.id)">
|
<div class="dropdown-item" @click="removePayment($route.params.id)">
|
||||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'trash']"
|
||||||
|
class="dropdown-item-icon"
|
||||||
|
/>
|
||||||
{{ $t('general.delete') }}
|
{{ $t('general.delete') }}
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown-item>
|
</v-dropdown-item>
|
||||||
@ -41,14 +61,18 @@
|
|||||||
align-icon="right"
|
align-icon="right"
|
||||||
@input="onSearch"
|
@input="onSearch"
|
||||||
/>
|
/>
|
||||||
<div
|
<div class="btn-group ml-3" role="group" aria-label="First group">
|
||||||
class="btn-group ml-3"
|
<v-dropdown
|
||||||
role="group"
|
:close-on-select="false"
|
||||||
aria-label="First group"
|
align="left"
|
||||||
|
class="filter-container"
|
||||||
>
|
>
|
||||||
<v-dropdown :close-on-select="false" align="left" class="filter-container">
|
|
||||||
<a slot="activator" href="#">
|
<a slot="activator" href="#">
|
||||||
<base-button class="inv-button inv-filter-fields-btn" color="default" size="medium">
|
<base-button
|
||||||
|
class="inv-button inv-filter-fields-btn"
|
||||||
|
color="default"
|
||||||
|
size="medium"
|
||||||
|
>
|
||||||
<font-awesome-icon icon="filter" />
|
<font-awesome-icon icon="filter" />
|
||||||
</base-button>
|
</base-button>
|
||||||
</a>
|
</a>
|
||||||
@ -64,8 +88,10 @@
|
|||||||
class="inv-radio"
|
class="inv-radio"
|
||||||
value="invoice_number"
|
value="invoice_number"
|
||||||
@change="onSearch"
|
@change="onSearch"
|
||||||
>
|
/>
|
||||||
<label class="inv-label" for="filter_invoice_number">{{ $t('invoices.title') }}</label>
|
<label class="inv-label" for="filter_invoice_number">{{
|
||||||
|
$t('invoices.title')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-items">
|
<div class="filter-items">
|
||||||
<input
|
<input
|
||||||
@ -76,8 +102,10 @@
|
|||||||
class="inv-radio"
|
class="inv-radio"
|
||||||
value="payment_date"
|
value="payment_date"
|
||||||
@change="onSearch"
|
@change="onSearch"
|
||||||
>
|
/>
|
||||||
<label class="inv-label" for="filter_payment_date">{{ $t('payments.date') }}</label>
|
<label class="inv-label" for="filter_payment_date">{{
|
||||||
|
$t('payments.date')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-items">
|
<div class="filter-items">
|
||||||
<input
|
<input
|
||||||
@ -88,11 +116,19 @@
|
|||||||
class="inv-radio"
|
class="inv-radio"
|
||||||
value="payment_number"
|
value="payment_number"
|
||||||
@change="onSearch"
|
@change="onSearch"
|
||||||
>
|
/>
|
||||||
<label class="inv-label" for="filter_payment_number">{{ $t('payments.payment_number') }}</label>
|
<label class="inv-label" for="filter_payment_number">{{
|
||||||
|
$t('payments.payment_number')
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
</v-dropdown>
|
</v-dropdown>
|
||||||
<base-button v-tooltip.top-center="{ content: getOrderName }" class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData">
|
<base-button
|
||||||
|
v-tooltip.top-center="{ content: getOrderName }"
|
||||||
|
class="inv-button inv-filter-sorting-btn"
|
||||||
|
color="default"
|
||||||
|
size="medium"
|
||||||
|
@click="sortData"
|
||||||
|
>
|
||||||
<font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" />
|
<font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" />
|
||||||
<font-awesome-icon v-else icon="sort-amount-down" />
|
<font-awesome-icon v-else icon="sort-amount-down" />
|
||||||
</base-button>
|
</base-button>
|
||||||
@ -101,7 +137,7 @@
|
|||||||
<base-loader v-if="isSearching" />
|
<base-loader v-if="isSearching" />
|
||||||
<div v-else class="side-content">
|
<div v-else class="side-content">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="(payment,index) in payments"
|
v-for="(payment, index) in payments"
|
||||||
:to="`/admin/payments/${payment.id}/view`"
|
:to="`/admin/payments/${payment.id}/view`"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="side-payment"
|
class="side-payment"
|
||||||
@ -112,7 +148,10 @@
|
|||||||
<div class="inv-number">{{ payment.invoice_number }}</div>
|
<div class="inv-number">{{ payment.invoice_number }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="inv-amount" v-html="$utils.formatMoney(payment.amount, payment.user.currency)" />
|
<div
|
||||||
|
class="inv-amount"
|
||||||
|
v-html="$utils.formatMoney(payment.amount, payment.user.currency)"
|
||||||
|
/>
|
||||||
<div class="inv-date">{{ payment.formattedPaymentDate }}</div>
|
<div class="inv-date">{{ payment.formattedPaymentDate }}</div>
|
||||||
<!-- <div class="inv-number">{{ payment.payment_method.name }}</div> -->
|
<!-- <div class="inv-number">{{ payment.payment_method.name }}</div> -->
|
||||||
</div>
|
</div>
|
||||||
@ -122,8 +161,8 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="payment-view-page-container" >
|
<div class="payment-view-page-container">
|
||||||
<iframe :src="`${shareableLink}`" class="frame-style"/>
|
<iframe :src="`${shareableLink}`" class="frame-style" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -260,6 +299,13 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
copyPdfUrl () {
|
||||||
|
let pdfUrl = `${window.location.origin}/payments/pdf/${this.payment.unique_hash}`
|
||||||
|
|
||||||
|
let response = this.$utils.copyTextToClipboard(pdfUrl)
|
||||||
|
|
||||||
|
window.toastr['success'](this.$tc('Copied PDF url to clipboard!'))
|
||||||
|
},
|
||||||
async removePayment (id) {
|
async removePayment (id) {
|
||||||
this.id = id
|
this.id = id
|
||||||
window.swal({
|
window.swal({
|
||||||
|
|||||||
@ -54,7 +54,8 @@ import {
|
|||||||
faEyeSlash,
|
faEyeSlash,
|
||||||
faSyncAlt,
|
faSyncAlt,
|
||||||
faRocket,
|
faRocket,
|
||||||
faCamera
|
faCamera,
|
||||||
|
faLink,
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { far } from '@fortawesome/free-regular-svg-icons'
|
import { far } from '@fortawesome/free-regular-svg-icons'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||||
@ -119,7 +120,8 @@ library.add(
|
|||||||
faPaperPlane,
|
faPaperPlane,
|
||||||
faSyncAlt,
|
faSyncAlt,
|
||||||
faRocket,
|
faRocket,
|
||||||
faCamera
|
faCamera,
|
||||||
|
faLink
|
||||||
)
|
)
|
||||||
|
|
||||||
Vue.component('font-awesome-icon', FontAwesomeIcon)
|
Vue.component('font-awesome-icon', FontAwesomeIcon)
|
||||||
|
|||||||
Reference in New Issue
Block a user