mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-10-31 05:31:10 -04:00 
			
		
		
		
	v6 update
This commit is contained in:
		
							
								
								
									
										275
									
								
								resources/scripts/customer/views/invoices/Index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								resources/scripts/customer/views/invoices/Index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,275 @@ | ||||
| <template> | ||||
|   <BasePage> | ||||
|     <!-- Page Header --> | ||||
|     <BasePageHeader :title="$t('invoices.title')"> | ||||
|       <BaseBreadcrumb> | ||||
|         <BaseBreadcrumbItem | ||||
|           :title="$t('general.home')" | ||||
|           :to="`/${globalStore.companySlug}/customer/dashboard`" | ||||
|         /> | ||||
|         <BaseBreadcrumbItem :title="$tc('invoices.invoice', 2)" to="#" active /> | ||||
|       </BaseBreadcrumb> | ||||
|       <template #actions> | ||||
|         <BaseButton | ||||
|           v-show="invoiceStore.totalInvoices" | ||||
|           variant="primary-outline" | ||||
|           @click="toggleFilter" | ||||
|         > | ||||
|           {{ $t('general.filter') }} | ||||
|           <template #right="slotProps"> | ||||
|             <BaseIcon | ||||
|               v-if="!showFilters" | ||||
|               name="FilterIcon" | ||||
|               :class="slotProps.class" | ||||
|             /> | ||||
|             <BaseIcon v-else name="XIcon" :class="slotProps.class" /> | ||||
|           </template> | ||||
|         </BaseButton> | ||||
|       </template> | ||||
|     </BasePageHeader> | ||||
|  | ||||
|     <BaseFilterWrapper v-show="showFilters" @clear="clearFilter"> | ||||
|       <BaseInputGroup :label="$t('invoices.status')" class="px-3"> | ||||
|         <BaseSelectInput | ||||
|           v-model="filters.status" | ||||
|           :options="status" | ||||
|           searchable | ||||
|           :allow-empty="false" | ||||
|           :placeholder="$t('general.select_a_status')" | ||||
|         /> | ||||
|       </BaseInputGroup> | ||||
|  | ||||
|       <BaseInputGroup | ||||
|         :label="$t('invoices.invoice_number')" | ||||
|         color="black-light" | ||||
|         class="px-3 mt-2" | ||||
|       > | ||||
|         <BaseInput v-model="filters.invoice_number"> | ||||
|           <BaseIcon name="DotsHorizontalIcon" class="h-5 text-gray-500" /> | ||||
|           <BaseIcon name="HashtagIcon" class="h-5 ml-3 text-gray-600" /> | ||||
|         </BaseInput> | ||||
|       </BaseInputGroup> | ||||
|  | ||||
|       <BaseInputGroup :label="$t('general.from')" class="px-3"> | ||||
|         <BaseDatePicker | ||||
|           v-model="filters.from_date" | ||||
|           :calendar-button="true" | ||||
|           calendar-button-icon="calendar" | ||||
|         /> | ||||
|       </BaseInputGroup> | ||||
|  | ||||
|       <div | ||||
|         class="hidden w-8 h-0 mx-4 border border-gray-400 border-solid xl:block" | ||||
|         style="margin-top: 1.5rem" | ||||
|       /> | ||||
|  | ||||
|       <BaseInputGroup :label="$t('general.to')" class="px-3"> | ||||
|         <BaseDatePicker | ||||
|           v-model="filters.to_date" | ||||
|           :calendar-button="true" | ||||
|           calendar-button-icon="calendar" | ||||
|         /> | ||||
|       </BaseInputGroup> | ||||
|     </BaseFilterWrapper> | ||||
|  | ||||
|     <BaseEmptyPlaceholder | ||||
|       v-if="showEmptyScreen" | ||||
|       :title="$t('invoices.no_invoices')" | ||||
|       :description="$t('invoices.list_of_invoices')" | ||||
|     > | ||||
|       <MoonwalkerIcon class="mt-5 mb-4" /> | ||||
|     </BaseEmptyPlaceholder> | ||||
|  | ||||
|     <div v-show="!showEmptyScreen" class="relative table-container"> | ||||
|       <BaseTable | ||||
|         ref="table" | ||||
|         :data="fetchData" | ||||
|         :columns="itemColumns" | ||||
|         :placeholder-count="invoiceStore.totalInvoices >= 20 ? 10 : 5" | ||||
|         class="mt-10" | ||||
|       > | ||||
|         <template #cell-invoice_date="{ row }"> | ||||
|           {{ row.data.formatted_invoice_date }} | ||||
|         </template> | ||||
|  | ||||
|         <template #cell-invoice_number="{ row }"> | ||||
|           <router-link | ||||
|             :to="{ path: `invoices/${row.data.id}/view` }" | ||||
|             class="font-medium text-primary-500" | ||||
|           > | ||||
|             {{ row.data.invoice_number }} | ||||
|           </router-link> | ||||
|         </template> | ||||
|  | ||||
|         <template #cell-due_amount="{ row }"> | ||||
|           <BaseFormatMoney | ||||
|             :amount="row.data.total" | ||||
|             :currency="row.data.customer.currency" | ||||
|           /> | ||||
|         </template> | ||||
|  | ||||
|         <template #cell-status="{ row }"> | ||||
|           <BaseInvoiceStatusBadge :status="row.data.status" class="px-3 py-1"> | ||||
|             {{ row.data.status }} | ||||
|           </BaseInvoiceStatusBadge> | ||||
|         </template> | ||||
|  | ||||
|         <template #cell-paid_status="{ row }"> | ||||
|           <BaseInvoiceStatusBadge | ||||
|             :status="row.data.paid_status" | ||||
|             class="px-3 py-1" | ||||
|           > | ||||
|             {{ row.data.paid_status }} | ||||
|           </BaseInvoiceStatusBadge> | ||||
|         </template> | ||||
|  | ||||
|         <template #cell-actions="{ row }"> | ||||
|           <BaseDropdown> | ||||
|             <template #activator> | ||||
|               <BaseIcon name="DotsHorizontalIcon" class="h-5 text-gray-500" /> | ||||
|             </template> | ||||
|             <router-link :to="`invoices/${row.data.id}/view`"> | ||||
|               <BaseDropdownItem> | ||||
|                 <BaseIcon name="EyeIcon" class="h-5 mr-3 text-gray-600" /> | ||||
|                 {{ $t('general.view') }} | ||||
|               </BaseDropdownItem> | ||||
|             </router-link> | ||||
|           </BaseDropdown> | ||||
|         </template> | ||||
|       </BaseTable> | ||||
|     </div> | ||||
|   </BasePage> | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| import { useInvoiceStore } from '@/scripts/customer/stores/invoice' | ||||
| import { debouncedWatch } from '@vueuse/core' | ||||
| import BaseTable from '@/scripts/components/base/base-table/BaseTable.vue' | ||||
| import { ref, computed, reactive, inject, onMounted } from 'vue' | ||||
| import { useGlobalStore } from '@/scripts/customer/stores/global' | ||||
| import { useRoute } from 'vue-router' | ||||
| import MoonwalkerIcon from '@/scripts/components/icons/empty/MoonwalkerIcon.vue' | ||||
| import { useI18n } from 'vue-i18n' | ||||
|  | ||||
| const { t } = useI18n() | ||||
|  | ||||
| //Utils | ||||
| const utils = inject('utils') | ||||
| const route = useRoute() | ||||
| // local state | ||||
| const table = ref(null) | ||||
| let isFetchingInitialData = ref(true) | ||||
| let showFilters = ref(false) | ||||
| const status = ref(['DRAFT', 'DUE', 'SENT', 'VIEWED', 'OVERDUE', 'COMPLETED']) | ||||
| const filters = reactive({ | ||||
|   status: '', | ||||
|   from_date: '', | ||||
|   to_date: '', | ||||
|   invoice_number: '', | ||||
| }) | ||||
|  | ||||
| // store | ||||
|  | ||||
| const invoiceStore = useInvoiceStore() | ||||
| const globalStore = useGlobalStore() | ||||
|  | ||||
| // Invoice Table columns Data | ||||
|  | ||||
| const currency = computed(() => { | ||||
|   return globalStore.currency | ||||
| }) | ||||
|  | ||||
| const itemColumns = computed(() => { | ||||
|   return [ | ||||
|     { | ||||
|       key: 'invoice_date', | ||||
|       label: t('invoices.date'), | ||||
|       thClass: 'extra', | ||||
|       tdClass: 'font-medium text-gray-900', | ||||
|     }, | ||||
|     { key: 'invoice_number', label: t('invoices.number') }, | ||||
|  | ||||
|     { key: 'status', label: t('invoices.status') }, | ||||
|     { key: 'paid_status', label: t('invoices.paid_status') }, | ||||
|     { | ||||
|       key: 'due_amount', | ||||
|       label: t('dashboard.recent_invoices_card.amount_due'), | ||||
|     }, | ||||
|     { | ||||
|       key: 'actions', | ||||
|       thClass: 'text-right', | ||||
|       tdClass: 'text-right text-sm font-medium', | ||||
|       sortable: false, | ||||
|     }, | ||||
|   ] | ||||
| }) | ||||
|  | ||||
| // computed props | ||||
|  | ||||
| const showEmptyScreen = computed(() => { | ||||
|   return !invoiceStore.totalInvoices && !isFetchingInitialData.value | ||||
| }) | ||||
|  | ||||
| //watch | ||||
|  | ||||
| debouncedWatch( | ||||
|   filters, | ||||
|   () => { | ||||
|     setFilters() | ||||
|   }, | ||||
|   { debounce: 500 } | ||||
| ) | ||||
|  | ||||
| //methods | ||||
|  | ||||
| function refreshTable() { | ||||
|   table.value.refresh() | ||||
| } | ||||
|  | ||||
| function setFilters() { | ||||
|   refreshTable() | ||||
| } | ||||
|  | ||||
| function clearFilter() { | ||||
|   filters.status = '' | ||||
|   filters.from_date = '' | ||||
|   filters.to_date = '' | ||||
|   filters.invoice_number = '' | ||||
| } | ||||
|  | ||||
| function toggleFilter() { | ||||
|   if (showFilters.value) { | ||||
|     clearFilter() | ||||
|   } | ||||
|  | ||||
|   showFilters.value = !showFilters.value | ||||
| } | ||||
|  | ||||
| async function fetchData({ page, sort }) { | ||||
|   let data = { | ||||
|     status: filters.status, | ||||
|     invoice_number: filters.invoice_number, | ||||
|     from_date: filters.from_date, | ||||
|     to_date: filters.to_date, | ||||
|     orderByField: sort.fieldName || 'created_at', | ||||
|     orderBy: sort.order || 'desc', | ||||
|     page, | ||||
|   } | ||||
|  | ||||
|   isFetchingInitialData.value = true | ||||
|  | ||||
|   let response = await invoiceStore.fetchInvoices(data, globalStore.companySlug) | ||||
|  | ||||
|   isFetchingInitialData.value = false | ||||
|  | ||||
|   return { | ||||
|     data: response.data.data, | ||||
|     pagination: { | ||||
|       totalPages: response.data.meta.last_page, | ||||
|       currentPage: page, | ||||
|       totalCount: response.data.meta.total, | ||||
|       limit: 10, | ||||
|     }, | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										405
									
								
								resources/scripts/customer/views/invoices/View.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								resources/scripts/customer/views/invoices/View.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,405 @@ | ||||
| <template> | ||||
|   <BasePage class="xl:pl-96"> | ||||
|     <BasePageHeader :title="pageTitle.invoice_number"> | ||||
|       <template #actions> | ||||
|         <BaseButton | ||||
|           :disabled="isSendingEmail" | ||||
|           variant="primary-outline" | ||||
|           class="mr-2" | ||||
|           tag="a" | ||||
|           :href="`/invoices/pdf/${invoice.unique_hash}`" | ||||
|           download | ||||
|         > | ||||
|           <template #left="slotProps"> | ||||
|             <BaseIcon name="DownloadIcon" :class="slotProps.class" /> | ||||
|             {{ $t('invoices.download') }} | ||||
|           </template> | ||||
|         </BaseButton> | ||||
|  | ||||
|         <BaseButton | ||||
|           v-if=" | ||||
|             invoiceStore?.selectedViewInvoice?.paid_status !== 'PAID' && | ||||
|             globalStore.enabledModules.includes('Payments') | ||||
|           " | ||||
|           variant="primary" | ||||
|           @click="payInvoice" | ||||
|         > | ||||
|           {{ $t('invoices.pay_invoice') }} | ||||
|         </BaseButton> | ||||
|       </template> | ||||
|     </BasePageHeader> | ||||
|  | ||||
|     <!-- Sidebar --> | ||||
|     <div | ||||
|       class="fixed top-0 left-0 hidden h-full pt-16 pb-4 bg-white w-88 xl:block" | ||||
|     > | ||||
|       <div | ||||
|         class=" | ||||
|           flex | ||||
|           items-center | ||||
|           justify-between | ||||
|           px-4 | ||||
|           pt-8 | ||||
|           pb-6 | ||||
|           border border-gray-200 border-solid | ||||
|         " | ||||
|       > | ||||
|         <BaseInput | ||||
|           v-model="searchData.invoice_number" | ||||
|           :placeholder="$t('general.search')" | ||||
|           type="text" | ||||
|           variant="gray" | ||||
|           @input="onSearch" | ||||
|         > | ||||
|           <template #right> | ||||
|             <BaseIcon name="SearchIcon" class="h-5 text-gray-400" /> | ||||
|           </template> | ||||
|         </BaseInput> | ||||
|  | ||||
|         <div class="flex ml-3" role="group" aria-label="First group"> | ||||
|           <BaseDropdown | ||||
|             position="bottom-start" | ||||
|             width-class="w-50" | ||||
|             position-class="left-0" | ||||
|           > | ||||
|             <template #activator> | ||||
|               <BaseButton variant="gray"> | ||||
|                 <BaseIcon name="FilterIcon" class="h-5" /> | ||||
|               </BaseButton> | ||||
|             </template> | ||||
|  | ||||
|             <div | ||||
|               class=" | ||||
|                 px-4 | ||||
|                 py-1 | ||||
|                 pb-2 | ||||
|                 mb-2 | ||||
|                 text-sm | ||||
|                 border-b border-gray-200 border-solid | ||||
|               " | ||||
|             > | ||||
|               {{ $t('general.sort_by') }} | ||||
|             </div> | ||||
|  | ||||
|             <div class="px-2"> | ||||
|               <BaseDropdownItem class="pt-3 rounded-md hover:rounded-md"> | ||||
|                 <BaseInputGroup class="-mt-3 font-normal"> | ||||
|                   <BaseRadio | ||||
|                     id="filter_invoice_date" | ||||
|                     v-model="searchData.orderByField" | ||||
|                     :label="$t('invoices.invoice_date')" | ||||
|                     name="filter" | ||||
|                     size="sm" | ||||
|                     value="invoice_date" | ||||
|                     @update:modelValue="onSearch" | ||||
|                   /> | ||||
|                 </BaseInputGroup> | ||||
|               </BaseDropdownItem> | ||||
|             </div> | ||||
|  | ||||
|             <div class="px-2"> | ||||
|               <BaseDropdownItem class="pt-3 rounded-md hover:rounded-md"> | ||||
|                 <BaseInputGroup class="-mt-3 font-normal"> | ||||
|                   <BaseRadio | ||||
|                     id="filter_due_date" | ||||
|                     v-model="searchData.orderByField" | ||||
|                     :label="$t('invoices.due_date')" | ||||
|                     name="filter" | ||||
|                     size="sm" | ||||
|                     value="due_date" | ||||
|                     @update:modelValue="onSearch" | ||||
|                   /> | ||||
|                 </BaseInputGroup> | ||||
|               </BaseDropdownItem> | ||||
|             </div> | ||||
|  | ||||
|             <div class="px-2"> | ||||
|               <BaseDropdownItem class="pt-3 rounded-md hover:rounded-md"> | ||||
|                 <BaseInputGroup class="-mt-3 font-normal"> | ||||
|                   <BaseRadio | ||||
|                     id="filter_invoice_number" | ||||
|                     v-model="searchData.orderByField" | ||||
|                     :label="$t('invoices.invoice_number')" | ||||
|                     size="sm" | ||||
|                     name="filter" | ||||
|                     value="invoice_number" | ||||
|                     @update:modelValue="onSearch" | ||||
|                   /> | ||||
|                 </BaseInputGroup> | ||||
|               </BaseDropdownItem> | ||||
|             </div> | ||||
|           </BaseDropdown> | ||||
|  | ||||
|           <BaseButton class="ml-1" variant="white" @click="sortData"> | ||||
|             <BaseIcon v-if="getOrderBy" name="SortAscendingIcon" class="h-5" /> | ||||
|             <BaseIcon v-else name="SortDescendingIcon" class="h-5" /> | ||||
|           </BaseButton> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <div | ||||
|         class=" | ||||
|           h-full | ||||
|           pb-32 | ||||
|           overflow-y-scroll | ||||
|           border-l border-gray-200 border-solid | ||||
|           sw-scroll | ||||
|         " | ||||
|       > | ||||
|         <router-link | ||||
|           v-for="(invoice, index) in invoiceStore.invoices" | ||||
|           :id="'invoice-' + invoice.id" | ||||
|           :key="index" | ||||
|           :to="`/${globalStore.companySlug}/customer/invoices/${invoice.id}/view`" | ||||
|           :class="[ | ||||
|             'flex justify-between p-4 items-center cursor-pointer hover:bg-gray-100 border-l-4 border-transparent', | ||||
|             { | ||||
|               'bg-gray-100 border-l-4 border-primary-500 border-solid': | ||||
|                 hasActiveUrl(invoice.id), | ||||
|             }, | ||||
|           ]" | ||||
|           style="border-bottom: 1px solid rgba(185, 193, 209, 0.41)" | ||||
|         > | ||||
|           <div class="flex-2"> | ||||
|             <div | ||||
|               class=" | ||||
|                 mb-1 | ||||
|                 not-italic | ||||
|                 font-medium | ||||
|                 leading-5 | ||||
|                 text-gray-500 | ||||
|                 capitalize | ||||
|                 text-md | ||||
|               " | ||||
|             > | ||||
|               {{ invoice.invoice_number }} | ||||
|             </div> | ||||
|             <BaseInvoiceStatusBadge :status="invoice.status"> | ||||
|               {{ invoice.status }} | ||||
|             </BaseInvoiceStatusBadge> | ||||
|           </div> | ||||
|  | ||||
|           <div class="flex-1 whitespace-nowrap right"> | ||||
|             <BaseFormatMoney | ||||
|               class=" | ||||
|                 mb-2 | ||||
|                 text-xl | ||||
|                 not-italic | ||||
|                 font-semibold | ||||
|                 leading-8 | ||||
|                 text-right text-gray-900 | ||||
|                 block | ||||
|               " | ||||
|               :amount="invoice.total" | ||||
|               :currency="invoice.currency" | ||||
|             /> | ||||
|  | ||||
|             <div class="text-sm text-right text-gray-500 non-italic"> | ||||
|               {{ invoice.formatted_invoice_date }} | ||||
|             </div> | ||||
|           </div> | ||||
|         </router-link> | ||||
|  | ||||
|         <p | ||||
|           v-if="!invoiceStore.invoices.length" | ||||
|           class="flex justify-center px-4 mt-5 text-sm text-gray-600" | ||||
|         > | ||||
|           {{ $t('invoices.no_matching_invoices') }} | ||||
|         </p> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- pdf --> | ||||
|     <div | ||||
|       class="flex flex-col min-h-0 mt-8 overflow-hidden" | ||||
|       style="height: 75vh" | ||||
|     > | ||||
|       <iframe | ||||
|         v-if="shareableLink" | ||||
|         ref="report" | ||||
|         :src="shareableLink" | ||||
|         class="flex-1 border border-gray-400 border-solid rounded-md" | ||||
|         @click="ViewReportsPDF" | ||||
|       /> | ||||
|     </div> | ||||
|   </BasePage> | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| import { useI18n } from 'vue-i18n' | ||||
| import BaseDropdown from '@/scripts/components/base/BaseDropdown.vue' | ||||
| import BaseDropdownItem from '@/scripts/components/base/BaseDropdownItem.vue' | ||||
| import { debounce } from 'lodash' | ||||
| import { ref, reactive, computed, inject, watch, onMounted } from 'vue' | ||||
| import { useRoute } from 'vue-router' | ||||
| import { useNotificationStore } from '@/scripts/stores/notification' | ||||
| import moment from 'moment' | ||||
| import { useInvoiceStore } from '@/scripts/customer/stores/invoice' | ||||
| import { useGlobalStore } from '@/scripts/customer/stores/global' | ||||
|  | ||||
| // Router | ||||
| const route = useRoute() | ||||
| //store | ||||
|  | ||||
| const invoiceStore = useInvoiceStore() | ||||
| const globalStore = useGlobalStore() | ||||
| const { tm } = useI18n() | ||||
|  | ||||
| //local state | ||||
| let invoice = reactive({}) | ||||
| let searchData = reactive({ | ||||
|   orderBy: '', | ||||
|   orderByField: '', | ||||
|   invoice_number: '', | ||||
|   // searchText: '', | ||||
| }) | ||||
|  | ||||
| let url = ref(null) | ||||
| let siteURL = ref(null) | ||||
| let isSearching = ref(false) | ||||
| let isSendingEmail = ref(false) | ||||
| let isMarkingAsSent = ref(false) | ||||
|  | ||||
| //Utils | ||||
| const utils = inject('utils') | ||||
|  | ||||
| //Store | ||||
|  | ||||
| const notificationStore = useNotificationStore() | ||||
|  | ||||
| // Computed Props | ||||
|  | ||||
| const pageTitle = computed(() => { | ||||
|   return invoiceStore.selectedViewInvoice | ||||
| }) | ||||
|  | ||||
| const getOrderBy = computed(() => { | ||||
|   if (searchData.orderBy === 'asc' || searchData.orderBy == null) { | ||||
|     return true | ||||
|   } | ||||
|   return false | ||||
| }) | ||||
|  | ||||
| const getOrderName = computed(() => | ||||
|   getOrderBy.value ? tm('general.ascending') : tm('general.descending') | ||||
| ) | ||||
|  | ||||
| const shareableLink = computed(() => { | ||||
|   return invoice.unique_hash ? `/invoices/pdf/${invoice.unique_hash}` : false | ||||
| }) | ||||
|  | ||||
| // Watcher | ||||
|  | ||||
| watch(route, () => { | ||||
|   loadInvoice() | ||||
| }) | ||||
|  | ||||
| // Created | ||||
|  | ||||
| loadInvoices() | ||||
| loadInvoice() | ||||
|  | ||||
| onSearch = debounce(onSearch, 500) | ||||
|  | ||||
| // Methods | ||||
|  | ||||
| function hasActiveUrl(id) { | ||||
|   return route.params.id == id | ||||
| } | ||||
|  | ||||
| async function loadInvoices() { | ||||
|   await invoiceStore.fetchInvoices( | ||||
|     { | ||||
|       limit: 'all', | ||||
|     }, | ||||
|     globalStore.companySlug | ||||
|   ) | ||||
|  | ||||
|   setTimeout(() => { | ||||
|     scrollToInvoice() | ||||
|   }, 500) | ||||
| } | ||||
|  | ||||
| async function loadInvoice() { | ||||
|   if (route && route.params.id) { | ||||
|     let response = await invoiceStore.fetchViewInvoice( | ||||
|       { | ||||
|         id: route.params.id, | ||||
|       }, | ||||
|       globalStore.companySlug | ||||
|     ) | ||||
|  | ||||
|     if (response.data) { | ||||
|       Object.assign(invoice, response.data.data) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| function scrollToInvoice() { | ||||
|   const el = document.getElementById(`invoice-${route.params.id}`) | ||||
|  | ||||
|   if (el) { | ||||
|     el.scrollIntoView({ behavior: 'smooth' }) | ||||
|     el.classList.add('shake') | ||||
|   } | ||||
| } | ||||
|  | ||||
| async function onSearch() { | ||||
|   let data = {} | ||||
|  | ||||
|   if ( | ||||
|     searchData.invoice_number !== '' && | ||||
|     searchData.invoice_number !== null && | ||||
|     searchData.invoice_number !== undefined | ||||
|   ) { | ||||
|     data.invoice_number = searchData.invoice_number | ||||
|   } | ||||
|  | ||||
|   if (searchData.orderBy !== null && searchData.orderBy !== undefined) { | ||||
|     data.orderBy = searchData.orderBy | ||||
|   } | ||||
|  | ||||
|   if ( | ||||
|     searchData.orderByField !== null && | ||||
|     searchData.orderByField !== undefined | ||||
|   ) { | ||||
|     data.orderByField = searchData.orderByField | ||||
|   } | ||||
|  | ||||
|   isSearching.value = true | ||||
|   try { | ||||
|     let response = await invoiceStore.searchInvoice( | ||||
|       data, | ||||
|       globalStore.companySlug | ||||
|     ) | ||||
|     isSearching.value = false | ||||
|  | ||||
|     if (response.data.data) { | ||||
|       invoiceStore.invoices = response.data.data | ||||
|     } | ||||
|   } catch (error) { | ||||
|     isSearching.value = false | ||||
|   } | ||||
| } | ||||
|  | ||||
| function sortData() { | ||||
|   if (searchData.orderBy === 'asc') { | ||||
|     searchData.orderBy = 'desc' | ||||
|     onSearch() | ||||
|     return true | ||||
|   } | ||||
|   searchData.orderBy = 'asc' | ||||
|   onSearch() | ||||
|   return true | ||||
| } | ||||
|  | ||||
| function payInvoice() { | ||||
|   router.push({ | ||||
|     name: 'invoice.portal.payment', | ||||
|     params: { | ||||
|       id: invoiceStore.selectedViewInvoice.id, | ||||
|       company: invoiceStore.selectedViewInvoice.company.slug, | ||||
|     }, | ||||
|   }) | ||||
| } | ||||
| </script> | ||||
		Reference in New Issue
	
	Block a user