- fix invoice status not updating issue

- date range selection issues on report for non-english languages
- fix invoice all tab issue (always showing draft even in all tab)
This commit is contained in:
Harsh Jagad
2022-02-24 05:22:32 +00:00
committed by Mohit Panjwani
parent 7202fdcbf2
commit 1322ed15dc
15 changed files with 268 additions and 61 deletions

View File

@ -40,7 +40,9 @@ class CheckInvoiceStatus extends Command
public function handle()
{
$date = Carbon::now();
$invoices = Invoice::where('status', '<>', Invoice::STATUS_COMPLETED)->whereDate('due_date', '<', $date)->get();
$invoices = Invoice::whereNotIn('status', [Invoice::STATUS_COMPLETED, Invoice::STATUS_DRAFT])
->whereDate('due_date', '<', $date)
->get();
foreach ($invoices as $invoice) {
$invoice->status = Invoice::STATUS_OVERDUE;

View File

@ -170,6 +170,8 @@ let estimateMailForm = reactive({
body: null,
})
const emit = defineEmits(['update'])
const modalActive = computed(() => {
return modalStore.active && modalStore.componentName === 'SendEstimateModal'
})
@ -249,6 +251,7 @@ async function submitForm() {
isLoading.value = false
if (response.data.success) {
emit('update')
closeSendEstimateModal()
return true
}

View File

@ -167,6 +167,8 @@ let isLoading = ref(false)
const templateUrl = ref('')
const isPreview = ref(false)
const emit = defineEmits(['update'])
const invoiceMailFields = ref([
'customer',
'customerCustom',
@ -263,6 +265,7 @@ async function submitForm() {
isLoading.value = false
if (response.data.success) {
emit('update', modalStore.id)
closeSendInvoiceModal()
return true
}

View File

@ -272,7 +272,7 @@ const router = useRouter()
let filters = reactive({
customer_id: '',
status: 'DRAFT',
status: '',
from_date: '',
to_date: '',
estimate_number: '',

View File

@ -1,5 +1,5 @@
<template>
<SendEstimateModal />
<SendEstimateModal @update="updateSentEstimate" />
<BasePage v-if="estimateData" class="xl:pl-96 xl:ml-8">
<BasePageHeader :title="pageTitle">
<template #actions>
@ -526,4 +526,15 @@ async function removeEstimate(id) {
}
})
}
function updateSentEstimate() {
let pos = estimateList.value.findIndex(
(estimate) => estimate.id === estimateData.value.id
)
if (estimateList.value[pos]) {
estimateList.value[pos].status = 'SENT'
estimateData.value.status = 'SENT'
}
}
</script>

View File

@ -299,7 +299,7 @@ const userStore = useUserStore()
let filters = reactive({
customer_id: '',
status: 'DRAFT',
status: '',
from_date: '',
to_date: '',
invoice_number: '',

View File

@ -212,13 +212,24 @@ function sortData() {
return true
}
function updateSentInvoice() {
let pos = invoiceList.value.findIndex(
(invoice) => invoice.id === invoiceData.value.id
)
if (invoiceList.value[pos]) {
invoiceList.value[pos].status = 'SENT'
invoiceData.value.status = 'SENT'
}
}
loadInvoices()
loadInvoice()
onSearched = debounce(onSearched, 500)
</script>
<template>
<SendInvoiceModal />
<SendInvoiceModal @update="updateSentInvoice" />
<BasePage v-if="invoiceData" class="xl:pl-96 xl:ml-8">
<BasePageHeader :title="pageTitle">

View File

@ -283,7 +283,7 @@ const router = useRouter()
let filters = reactive({
customer_id: '',
status: 'ACTIVE',
status: '',
from_date: '',
to_date: '',
})

View File

@ -27,12 +27,7 @@
to="#"
active
/>
<BaseBreadcrumbItem
v-else
:title="pageTitle"
to="#"
active
/>
<BaseBreadcrumbItem v-else :title="pageTitle" to="#" active />
</BaseBreadcrumb>
<template #actions>
@ -143,6 +138,8 @@
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useModalStore } from '@/scripts/stores/modal'
import CreateItems from '@/scripts/admin/components/estimate-invoice-common/CreateItems.vue'
import CreateTotal from '@/scripts/admin/components/estimate-invoice-common/CreateTotal.vue'
import SelectTemplateButton from '@/scripts/admin/components/estimate-invoice-common/SelectTemplateButton.vue'
@ -165,6 +162,7 @@ import { useCompanyStore } from '@/scripts/admin/stores/company'
import { useCustomFieldStore } from '@/scripts/admin/stores/custom-field'
import { useRecurringInvoiceStore } from '@/scripts/admin/stores/recurring-invoice'
import { useModuleStore } from '@/scripts/admin/stores/module'
import { useCustomerStore } from '@/scripts/admin/stores/customer'
import SelectTemplateModal from '@/scripts/admin/components/modal-components/SelectTemplateModal.vue'
import TaxTypeModal from '@/scripts/admin/components/modal-components/TaxTypeModal.vue'
import ItemModal from '@/scripts/admin/components/modal-components/ItemModal.vue'
@ -173,7 +171,10 @@ const recurringInvoiceStore = useRecurringInvoiceStore()
const companyStore = useCompanyStore()
const customFieldStore = useCustomFieldStore()
const moduleStore = useModuleStore()
const modalStore = useModalStore()
const customerStore = useCustomerStore()
const recurringInvoiceValidationScope = 'newRecurringInvoice'
const notificationStore = useNotificationStore()
const { t } = useI18n()
let isSaving = ref(false)
@ -292,6 +293,16 @@ async function submitForm() {
tax: recurringInvoiceStore.getTotalTax,
}
if (data.customer && !data.customer.email && data.send_automatically) {
notificationStore.showNotification({
type: 'error',
message: t('recurring_invoices.add_customer_email'),
})
editCustomer()
isSaving.value = false
return
}
if (route.params.id) {
recurringInvoiceStore
.updateRecurringInvoice(data)
@ -309,6 +320,16 @@ async function submitForm() {
}
}
async function editCustomer() {
let selectedCustomer = recurringInvoiceStore.newRecurringInvoice.customer.id
await customerStore.fetchCustomer(selectedCustomer)
modalStore.openModal({
title: t('customers.edit_customer'),
componentName: 'CustomerModal',
})
}
function submitCreate(data) {
recurringInvoiceStore
.addRecurringInvoice(data)

View File

@ -1,5 +1,5 @@
<template>
<SendInvoiceModal />
<SendInvoiceModal @update="updateSentInvoiceStatus" />
<div class="relative table-container">
<BaseTable
ref="table"
@ -97,4 +97,14 @@ function hasAtleastOneAbility() {
function refreshTable() {
table.value && table.value.refresh()
}
function updateSentInvoiceStatus(id) {
let pos = recurringInvoiceStore.newRecurringInvoice.invoices.findIndex(
(invoice) => invoice.id === id
)
if (recurringInvoiceStore.newRecurringInvoice.invoices[pos]) {
recurringInvoiceStore.newRecurringInvoice.invoices[pos].status = 'SENT'
}
}
</script>

View File

@ -8,6 +8,10 @@
<BaseMultiselect
v-model="selectedRange"
:options="dateRange"
value-prop="key"
track-by="key"
label="label"
object
@update:modelValue="onChangeDateRange"
/>
</BaseInputGroup>
@ -97,19 +101,49 @@ const { t } = useI18n()
globalStore.downloadReport = downloadReport
const dateRange = reactive([
t('dateRange.today'),
t('dateRange.this_week'),
t('dateRange.this_month'),
t('dateRange.this_quarter'),
t('dateRange.this_year'),
t('dateRange.previous_week'),
t('dateRange.previous_month'),
t('dateRange.previous_quarter'),
t('dateRange.previous_year'),
t('dateRange.custom'),
{
label: t('dateRange.today'),
key: 'Today',
},
{
label: t('dateRange.this_week'),
key: 'This Week',
},
{
label: t('dateRange.this_month'),
key: 'This Month',
},
{
label: t('dateRange.this_quarter'),
key: 'This Quarter',
},
{
label: t('dateRange.this_year'),
key: 'This Year',
},
{
label: t('dateRange.previous_week'),
key: 'Previous Week',
},
{
label: t('dateRange.previous_month'),
key: 'Previous Month',
},
{
label: t('dateRange.previous_quarter'),
key: 'Previous Quarter',
},
{
label: t('dateRange.previous_year'),
key: 'Previous Year',
},
{
label: t('dateRange.custom'),
key: 'Custom',
},
])
const selectedRange = ref(t('dateRange.this_month'))
const selectedRange = ref(dateRange[2])
let range = ref(new Date())
let url = ref(null)
let siteURL = ref(null)
@ -155,7 +189,9 @@ function getPreDate(type, time) {
}
function onChangeDateRange() {
switch (selectedRange.value) {
let key = selectedRange.value.key
switch (key) {
case 'Today':
formData.from_date = moment().format('YYYY-MM-DD')
formData.to_date = moment().format('YYYY-MM-DD')

View File

@ -8,6 +8,10 @@
<BaseMultiselect
v-model="selectedRange"
:options="dateRange"
value-prop="key"
track-by="key"
label="label"
object
@update:modelValue="onChangeDateRange"
/>
</BaseInputGroup>
@ -95,18 +99,49 @@ const { t } = useI18n()
globalStore.downloadReport = downloadReport
const dateRange = reactive([
t('dateRange.today'),
t('dateRange.this_week'),
t('dateRange.this_month'),
t('dateRange.this_quarter'),
t('dateRange.this_year'),
t('dateRange.previous_week'),
t('dateRange.previous_month'),
t('dateRange.previous_quarter'),
t('dateRange.previous_year'),
t('dateRange.custom'),
{
label: t('dateRange.today'),
key: 'Today',
},
{
label: t('dateRange.this_week'),
key: 'This Week',
},
{
label: t('dateRange.this_month'),
key: 'This Month',
},
{
label: t('dateRange.this_quarter'),
key: 'This Quarter',
},
{
label: t('dateRange.this_year'),
key: 'This Year',
},
{
label: t('dateRange.previous_week'),
key: 'Previous Week',
},
{
label: t('dateRange.previous_month'),
key: 'Previous Month',
},
{
label: t('dateRange.previous_quarter'),
key: 'Previous Quarter',
},
{
label: t('dateRange.previous_year'),
key: 'Previous Year',
},
{
label: t('dateRange.custom'),
key: 'Custom',
},
])
const selectedRange = ref(t('dateRange.this_month'))
const selectedRange = ref(dateRange[2])
let url = ref(null)
let siteURL = ref(null)
let range = ref(new Date())
@ -149,7 +184,9 @@ function getPreDate(type, time) {
}
function onChangeDateRange() {
switch (selectedRange.value) {
let key = selectedRange.value.key
switch (key) {
case 'Today':
formData.from_date = moment().format('YYYY-MM-DD')
formData.to_date = moment().format('YYYY-MM-DD')

View File

@ -8,6 +8,10 @@
<BaseMultiselect
v-model="selectedRange"
:options="dateRange"
value-prop="key"
track-by="key"
label="label"
object
@update:modelValue="onChangeDateRange"
/>
</BaseInputGroup>
@ -109,21 +113,51 @@ const globalStore = useGlobalStore()
globalStore.downloadReport = downloadReport
const dateRange = reactive([
t('dateRange.today'),
t('dateRange.this_week'),
t('dateRange.this_month'),
t('dateRange.this_quarter'),
t('dateRange.this_year'),
t('dateRange.previous_week'),
t('dateRange.previous_month'),
t('dateRange.previous_quarter'),
t('dateRange.previous_year'),
t('dateRange.custom'),
{
label: t('dateRange.today'),
key: 'Today',
},
{
label: t('dateRange.this_week'),
key: 'This Week',
},
{
label: t('dateRange.this_month'),
key: 'This Month',
},
{
label: t('dateRange.this_quarter'),
key: 'This Quarter',
},
{
label: t('dateRange.this_year'),
key: 'This Year',
},
{
label: t('dateRange.previous_week'),
key: 'Previous Week',
},
{
label: t('dateRange.previous_month'),
key: 'Previous Month',
},
{
label: t('dateRange.previous_quarter'),
key: 'Previous Quarter',
},
{
label: t('dateRange.previous_year'),
key: 'Previous Year',
},
{
label: t('dateRange.custom'),
key: 'Custom',
},
])
const selectedRange = ref(dateRange[2])
const reportTypes = ref(['By Customer', 'By Item'])
const selectedType = ref('By Customer')
const selectedRange = ref(t('dateRange.this_month'))
let range = ref(new Date())
let url = ref(null)
let customerSiteURL = ref(null)
@ -178,7 +212,9 @@ function getPreDate(type, time) {
}
function onChangeDateRange() {
switch (selectedRange.value) {
let key = selectedRange.value.key
switch (key) {
case 'Today':
formData.from_date = moment().format('YYYY-MM-DD')
formData.to_date = moment().format('YYYY-MM-DD')

View File

@ -8,6 +8,10 @@
<BaseMultiselect
v-model="selectedRange"
:options="dateRange"
value-prop="key"
track-by="key"
label="label"
object
@update:modelValue="onChangeDateRange"
/>
</BaseInputGroup>
@ -94,19 +98,49 @@ globalStore.downloadReport = downloadReport
const { t } = useI18n()
const dateRange = reactive([
t('dateRange.today'),
t('dateRange.this_week'),
t('dateRange.this_month'),
t('dateRange.this_quarter'),
t('dateRange.this_year'),
t('dateRange.previous_week'),
t('dateRange.previous_month'),
t('dateRange.previous_quarter'),
t('dateRange.previous_year'),
t('dateRange.custom'),
{
label: t('dateRange.today'),
key: 'Today',
},
{
label: t('dateRange.this_week'),
key: 'This Week',
},
{
label: t('dateRange.this_month'),
key: 'This Month',
},
{
label: t('dateRange.this_quarter'),
key: 'This Quarter',
},
{
label: t('dateRange.this_year'),
key: 'This Year',
},
{
label: t('dateRange.previous_week'),
key: 'Previous Week',
},
{
label: t('dateRange.previous_month'),
key: 'Previous Month',
},
{
label: t('dateRange.previous_quarter'),
key: 'Previous Quarter',
},
{
label: t('dateRange.previous_year'),
key: 'Previous Year',
},
{
label: t('dateRange.custom'),
key: 'Custom',
},
])
const selectedRange = ref(t('dateRange.this_month'))
const selectedRange = ref(dateRange[2])
const formData = reactive({
from_date: moment().startOf('month').format('YYYY-MM-DD').toString(),
@ -153,7 +187,9 @@ function getPreDate(type, time) {
}
function onChangeDateRange() {
switch (selectedRange.value) {
let key = selectedRange.value.key
switch (key) {
case 'Today':
formData.from_date = moment().format('YYYY-MM-DD')
formData.to_date = moment().format('YYYY-MM-DD')

View File

@ -526,6 +526,7 @@
"cloned_successfully": "Recurring Invoice cloned successfully",
"clone_invoice": "Clone Recurring Invoice",
"confirm_clone": "This recurring invoice will be cloned into a new Recurring Invoice",
"add_customer_email": "Please add an email address for this customer to send invoices automatically.",
"item": {
"title": "Item Title",
"description": "Description",