Fix invoice status issue

This commit is contained in:
Harsh Jagad
2022-03-30 07:38:38 +00:00
committed by Mohit Panjwani
parent a9e54981bf
commit c4c00002d7
10 changed files with 858 additions and 1287 deletions

View File

@ -103,6 +103,7 @@ class CustomerStatsController extends Controller
) )
->whereCompany() ->whereCompany()
->whereCustomer($customer->id) ->whereCustomer($customer->id)
->where('status', '<>', Invoice::STATUS_DRAFT)
->sum('total'); ->sum('total');
$totalReceipts = Payment::whereBetween( $totalReceipts = Payment::whereBetween(
'payment_date', 'payment_date',

View File

@ -104,6 +104,7 @@ class DashboardController extends Controller
'invoice_date', 'invoice_date',
[$startDate->format('Y-m-d'), $start->format('Y-m-d')] [$startDate->format('Y-m-d'), $start->format('Y-m-d')]
) )
->where('status', '<>', Invoice::STATUS_DRAFT)
->whereCompany() ->whereCompany()
->sum('base_total'); ->sum('base_total');
@ -141,6 +142,7 @@ class DashboardController extends Controller
$recent_due_invoices = Invoice::with('customer') $recent_due_invoices = Invoice::with('customer')
->whereCompany() ->whereCompany()
->where('base_due_amount', '>', 0) ->where('base_due_amount', '>', 0)
->where('status', '<>', Invoice::STATUS_DRAFT)
->take(5) ->take(5)
->latest() ->latest()
->get(); ->get();

View File

@ -24,6 +24,7 @@ class InvoicesController extends Controller
$limit = $request->has('limit') ? $request->limit : 10; $limit = $request->has('limit') ? $request->limit : 10;
$invoices = Invoice::whereCompany() $invoices = Invoice::whereCompany()
->whereTabFilters($request->tab_status)
->join('customers', 'customers.id', '=', 'invoices.customer_id') ->join('customers', 'customers.id', '=', 'invoices.customer_id')
->applyFilters($request->all()) ->applyFilters($request->all())
->select('invoices.*', 'customers.name') ->select('invoices.*', 'customers.name')

View File

@ -187,16 +187,6 @@ class Invoice extends Model implements HasMedia
return Carbon::parse($this->invoice_date)->format($dateFormat); return Carbon::parse($this->invoice_date)->format($dateFormat);
} }
public function scopeWhereStatus($query, $status)
{
return $query->where('invoices.status', $status);
}
public function scopeWherePaidStatus($query, $status)
{
return $query->where('invoices.paid_status', $status);
}
public function scopeWhereDueStatus($query, $status) public function scopeWhereDueStatus($query, $status)
{ {
return $query->whereIn('invoices.paid_status', [ return $query->whereIn('invoices.paid_status', [
@ -234,6 +224,40 @@ class Invoice extends Model implements HasMedia
$query->orderBy($orderByField, $orderBy); $query->orderBy($orderByField, $orderBy);
} }
public function scopeWhereStatus($query, $status)
{
return $query->where('invoices.status', $status);
}
public function scopeWherePaidStatus($query, $status)
{
return $query->where('invoices.paid_status', $status);
}
public function scopeWhereTabFilters($query, $status)
{
if ($status == "DRAFT") {
return $query->where('invoices.status', $status);
}
if ($status == "SENT") {
return $query->whereIn('invoices.status', [
self::STATUS_SENT,
self::STATUS_VIEWED,
self::STATUS_COMPLETED
]);
}
if ($status == 'DUE') {
return $query->whereIn('invoices.paid_status', [
self::STATUS_UNPAID,
self::STATUS_PARTIALLY_PAID,
]);
}
return ;
}
public function scopeApplyFilters($query, array $filters) public function scopeApplyFilters($query, array $filters)
{ {
$filters = collect($filters); $filters = collect($filters);
@ -249,17 +273,11 @@ class Invoice extends Model implements HasMedia
$filters->get('status') == self::STATUS_PAID $filters->get('status') == self::STATUS_PAID
) { ) {
$query->wherePaidStatus($filters->get('status')); $query->wherePaidStatus($filters->get('status'));
} elseif ($filters->get('status') == 'DUE') {
$query->whereDueStatus($filters->get('status'));
} else { } else {
$query->whereStatus($filters->get('status')); $query->whereStatus($filters->get('status'));
} }
} }
if ($filters->get('paid_status')) {
$query->wherePaidStatus($filters->get('status'));
}
if ($filters->get('invoice_id')) { if ($filters->get('invoice_id')) {
$query->whereInvoice($filters->get('invoice_id')); $query->whereInvoice($filters->get('invoice_id'));
} }

View File

@ -27,7 +27,7 @@
"vite": "^2.6.1" "vite": "^2.6.1"
}, },
"dependencies": { "dependencies": {
"@headlessui/vue": "^1.4.0", "@headlessui/vue": "^1.5.0",
"@heroicons/vue": "^1.0.1", "@heroicons/vue": "^1.0.1",
"@popperjs/core": "^2.9.2", "@popperjs/core": "^2.9.2",
"@stripe/stripe-js": "^1.21.2", "@stripe/stripe-js": "^1.21.2",
@ -48,7 +48,7 @@
"mini-svg-data-uri": "^1.3.3", "mini-svg-data-uri": "^1.3.3",
"moment": "^2.29.1", "moment": "^2.29.1",
"pinia": "^2.0.4", "pinia": "^2.0.4",
"v-money3": "^3.13.5", "v-money3": "3.16.1",
"v-tooltip": "^4.0.0-alpha.1", "v-tooltip": "^4.0.0-alpha.1",
"vue": "^3.2.0-beta.5", "vue": "^3.2.0-beta.5",
"vue-flatpickr-component": "^9.0.3", "vue-flatpickr-component": "^9.0.3",

View File

@ -56,7 +56,7 @@
<BaseMultiselect <BaseMultiselect
v-model="filters.status" v-model="filters.status"
:groups="true" :groups="true"
:options="status" :options="invoiceStatus"
searchable searchable
:placeholder="$t('general.select_a_status')" :placeholder="$t('general.select_a_status')"
@update:modelValue="setActiveTab" @update:modelValue="setActiveTab"
@ -130,11 +130,27 @@
" "
> >
<!-- Tabs --> <!-- Tabs -->
<BaseTabGroup class="-mb-5" @change="setStatusFilter"> <BaseTabGroup
<BaseTab :title="$t('general.all')" filter="" /> class="-mb-5"
<BaseTab :title="$t('general.draft')" filter="DRAFT" /> :selected-index="selectedIndex"
<BaseTab :title="$t('general.sent')" filter="SENT" /> @change="changeTabStatus"
<BaseTab :title="$t('general.due')" filter="DUE" /> >
<BaseTab
:title="invoiceTabStatus[0].title"
:tab-status="invoiceTabStatus[0].value"
/>
<BaseTab
:title="invoiceTabStatus[1].title"
:tab-status="invoiceTabStatus[1].value"
/>
<BaseTab
:title="invoiceTabStatus[2].title"
:tab-status="invoiceTabStatus[2].value"
/>
<BaseTab
:title="invoiceTabStatus[3].title"
:tab-status="invoiceTabStatus[3].value"
/>
</BaseTabGroup> </BaseTabGroup>
<BaseDropdown <BaseDropdown
@ -289,10 +305,10 @@ const utils = inject('$utils')
const table = ref(null) const table = ref(null)
const showFilters = ref(false) const showFilters = ref(false)
const status = ref([ const invoiceStatus = ref([
{ {
label: 'Status', label: 'Status',
options: ['DRAFT', 'DUE', 'SENT', 'VIEWED', 'COMPLETED'], options: ['DRAFT', 'SENT', 'VIEWED', 'COMPLETED'],
}, },
{ {
label: 'Paid Status', label: 'Paid Status',
@ -300,10 +316,29 @@ const status = ref([
}, },
, ,
]) ])
const invoiceTabStatus = {
0: {
title: t('general.all'),
value: '',
},
1: {
title: t('general.draft'),
value: 'DRAFT',
},
2: {
title: t('general.sent'),
value: 'SENT',
},
3: {
title: t('general.due'),
value: 'DUE',
},
}
const isRequestOngoing = ref(true) const isRequestOngoing = ref(true)
const activeTab = ref('general.draft')
const router = useRouter() const router = useRouter()
const userStore = useUserStore() const userStore = useUserStore()
const selectedIndex = ref(0)
let filters = reactive({ let filters = reactive({
customer_id: '', customer_id: '',
@ -311,6 +346,7 @@ let filters = reactive({
from_date: '', from_date: '',
to_date: '', to_date: '',
invoice_number: '', invoice_number: '',
tab_status: '',
}) })
const showEmptyScreen = computed( const showEmptyScreen = computed(
@ -401,6 +437,7 @@ async function fetchData({ page, filter, sort }) {
from_date: filters.from_date, from_date: filters.from_date,
to_date: filters.to_date, to_date: filters.to_date,
invoice_number: filters.invoice_number, invoice_number: filters.invoice_number,
tab_status: filters.tab_status,
orderByField: sort.fieldName || 'created_at', orderByField: sort.fieldName || 'created_at',
orderBy: sort.order || 'desc', orderBy: sort.order || 'desc',
page, page,
@ -423,29 +460,9 @@ async function fetchData({ page, filter, sort }) {
} }
} }
function setStatusFilter(val) { function changeTabStatus(val, index) {
if (activeTab.value == val.title) { filters.tab_status = val['tab-status']
return true selectedIndex.value = index
}
activeTab.value = val.title
switch (val.title) {
case t('general.draft'):
filters.status = 'DRAFT'
break
case t('general.sent'):
filters.status = 'SENT'
break
case t('general.due'):
filters.status = 'DUE'
break
default:
filters.status = ''
break
}
} }
function setFilters() { function setFilters() {
@ -463,8 +480,6 @@ function clearFilter() {
filters.from_date = '' filters.from_date = ''
filters.to_date = '' filters.to_date = ''
filters.invoice_number = '' filters.invoice_number = ''
activeTab.value = t('general.all')
} }
async function removeMultipleInvoices() { async function removeMultipleInvoices() {
@ -505,39 +520,21 @@ function toggleFilter() {
function setActiveTab(val) { function setActiveTab(val) {
switch (val) { switch (val) {
case 'DRAFT': case 'DRAFT':
activeTab.value = t('general.draft') selectedIndex.value = 1
break break
case 'SENT': case 'SENT':
activeTab.value = t('general.sent') case 'VIEWED':
break
case 'DUE':
activeTab.value = t('general.due')
break
case 'COMPLETED': case 'COMPLETED':
activeTab.value = t('invoices.completed')
break
case 'PAID': case 'PAID':
activeTab.value = t('invoices.paid') selectedIndex.value = 2
break break
case 'UNPAID': case 'UNPAID':
activeTab.value = t('invoices.unpaid')
break
case 'PARTIALLY_PAID': case 'PARTIALLY_PAID':
activeTab.value = t('invoices.partially_paid') selectedIndex.value = 3
break
case 'VIEWED':
activeTab.value = t('invoices.viewed')
break
default:
activeTab.value = t('general.all')
break break
} }
filters.tab_status = invoiceTabStatus[selectedIndex.value].value
} }
</script> </script>

View File

@ -82,9 +82,9 @@
required required
> >
<BaseCustomerSelectInput <BaseCustomerSelectInput
v-if="!isLoadingContent"
v-model="paymentStore.currentPayment.customer_id" v-model="paymentStore.currentPayment.customer_id"
:content-loading="isLoadingContent" :content-loading="isLoadingContent"
v-if="!isLoadingContent"
:invalid="v$.currentPayment.customer_id.$error" :invalid="v$.currentPayment.customer_id.$error"
:placeholder="$t('customers.select_a_customer')" :placeholder="$t('customers.select_a_customer')"
show-action show-action
@ -423,7 +423,7 @@ function onCustomerChange(customer_id) {
if (customer_id) { if (customer_id) {
let data = { let data = {
customer_id: customer_id, customer_id: customer_id,
status: 'DUE', tab_status: 'DUE',
limit: 'all', limit: 'all',
} }
@ -446,7 +446,11 @@ function onCustomerChange(customer_id) {
paymentStore.currentPayment.selectedCustomer = res2.data.data paymentStore.currentPayment.selectedCustomer = res2.data.data
paymentStore.currentPayment.customer = res2.data.data paymentStore.currentPayment.customer = res2.data.data
paymentStore.currentPayment.currency = res2.data.data.currency paymentStore.currentPayment.currency = res2.data.data.currency
if(isEdit.value && !customerStore.editCustomer && paymentStore.currentPayment.customer_id) { if (
isEdit.value &&
!customerStore.editCustomer &&
paymentStore.currentPayment.customer_id
) {
customerStore.editCustomer = res2.data.data customerStore.editCustomer = res2.data.data
} }
} }

View File

@ -1,6 +1,10 @@
<template> <template>
<div> <div>
<TabGroup :default-index="defaultIndex" @change="onChange"> <TabGroup
:selected-index="selectedIndex"
:default-index="defaultIndex"
@change="onChange"
>
<TabList <TabList
:class="[ :class="[
'flex border-b border-grey-light', 'flex border-b border-grey-light',
@ -54,6 +58,10 @@ const props = defineProps({
type: Number, type: Number,
default: 0, default: 0,
}, },
selectedIndex: {
type: Number,
default: 0,
},
filter: { filter: {
type: String, type: String,
default: null, default: null,
@ -67,6 +75,6 @@ const slots = useSlots()
const tabs = computed(() => slots.default().map((tab) => tab.props)) const tabs = computed(() => slots.default().map((tab) => tab.props))
function onChange(d) { function onChange(d) {
emit('change', tabs.value[d]) emit('change', tabs.value[d], d)
} }
</script> </script>

View File

@ -7,12 +7,12 @@ export function usePopper(options) {
let popper = ref(null) let popper = ref(null)
onMounted(() => { onMounted(() => {
watchEffect(onInvalidate => { watchEffect((onInvalidate) => {
if (!container.value) return if (!container.value) return
if (!activator.value) return if (!activator.value) return
let containerEl = container.value.el || container.value let containerEl = container.value.el || container.value
let activatorEl = activator.value.el || activator.value let activatorEl = activator.value.$el || activator.value
if (!(activatorEl instanceof HTMLElement)) return if (!(activatorEl instanceof HTMLElement)) return
if (!(containerEl instanceof HTMLElement)) return if (!(containerEl instanceof HTMLElement)) return

1948
yarn.lock

File diff suppressed because it is too large Load Diff