mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-10-31 13:41:09 -04:00 
			
		
		
		
	init crater
This commit is contained in:
		
							
								
								
									
										351
									
								
								resources/assets/js/views/expenses/Create.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										351
									
								
								resources/assets/js/views/expenses/Create.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,351 @@ | ||||
| <template> | ||||
|   <div class="main-content expenses"> | ||||
|     <form action="" @submit.prevent="sendData"> | ||||
|       <div class="page-header"> | ||||
|         <h3 class="page-title">{{ isEdit ? $t('expenses.edit_expense') : $t('expenses.new_expense') }}</h3> | ||||
|         <ol class="breadcrumb"> | ||||
|           <li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('general.home') }}</router-link></li> | ||||
|           <li class="breadcrumb-item"><router-link slot="item-title" to="/admin/expenses">{{ $tc('expenses.expense', 2) }}</router-link></li> | ||||
|           <li class="breadcrumb-item"><a href="#">{{ isEdit ? $t('expenses.edit_expense') : $t('expenses.new_expense') }}</a></li> | ||||
|         </ol> | ||||
|         <div class="page-actions row header-button-container"> | ||||
|           <div v-if="isReceiptAvailable" class="col-xs-2 mr-4"> | ||||
|             <a :href="getReceiptUrl"> | ||||
|               <base-button | ||||
|                 :loading="isLoading" | ||||
|                 icon="download" | ||||
|                 color="theme" | ||||
|                 outline | ||||
|               > | ||||
|                 {{ $t('expenses.download_receipt') }} | ||||
|               </base-button> | ||||
|             </a> | ||||
|           </div> | ||||
|           <div class="col-xs-2"> | ||||
|             <base-button | ||||
|               :loading="isLoading" | ||||
|               icon="save" | ||||
|               color="theme" | ||||
|               type="submit" | ||||
|             > | ||||
|               {{ isEdit ? $t('expenses.update_expense') : $t('expenses.save_expense') }} | ||||
|             </base-button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="row"> | ||||
|         <div class="col-sm-12"> | ||||
|           <div class="card"> | ||||
|             <div class="card-body"> | ||||
|               <div class="row"> | ||||
|                 <!-- <div class="form-group col-sm-6"> | ||||
|                   <label class="control-label">{{ $t('expenses.expense_title') }}</label> | ||||
|                   <input v-model="formData.title" type="text" name="name" class="form-control"> | ||||
|                 </div> --> | ||||
|                 <div class="form-group col-sm-6"> | ||||
|                   <label class="control-label">{{ $t('expenses.category') }}</label><span class="text-danger"> * </span> | ||||
|                   <base-select | ||||
|                     ref="baseSelect" | ||||
|                     v-model="category" | ||||
|                     :options="categories" | ||||
|                     :invalid="$v.category.$error" | ||||
|                     :searchable="true" | ||||
|                     :show-labels="false" | ||||
|                     :placeholder="$t('expenses.categories.select_a_category')" | ||||
|                     label="name" | ||||
|                     track-by="id" | ||||
|                     @input="$v.category.$touch()" | ||||
|                   > | ||||
|                     <div slot="afterList"> | ||||
|                       <button type="button" class="list-add-button" @click="openCategoryModal"> | ||||
|                         <font-awesome-icon class="icon" icon="cart-plus" /> | ||||
|                         <label>{{ $t('settings.expense_category.add_new_category') }}</label> | ||||
|                       </button> | ||||
|                     </div> | ||||
|                   </base-select> | ||||
|                   <div v-if="$v.category.$error"> | ||||
|                     <span v-if="!$v.category.required" class="text-danger">{{ $t('validation.required') }}</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <!-- <div class="form-group col-sm-6"> | ||||
|                   <label>{{ $t('expenses.contact') }}</label> | ||||
|                   <select v-model="formData.contact" name="contact" class="form-control ls-select2"> | ||||
|                     <option v-for="(contact, index) in contacts" :key="index" :value="contact.id"> {{ contact.name }}</option> | ||||
|                   </select> | ||||
|                 </div> --> | ||||
|                 <div class="form-group col-sm-6"> | ||||
|                   <label>{{ $t('expenses.expense_date') }}</label><span class="text-danger"> * </span> | ||||
|                   <base-date-picker | ||||
|                     v-model="formData.expense_date" | ||||
|                     :invalid="$v.formData.expense_date.$error" | ||||
|                     :calendar-button="true" | ||||
|                     calendar-button-icon="calendar" | ||||
|                     @change="$v.formData.expense_date.$touch()" | ||||
|                   /> | ||||
|                   <div v-if="$v.formData.expense_date.$error"> | ||||
|                     <span v-if="!$v.formData.expense_date.required" class="text-danger">{{ $t('validation.required') }}</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="form-group col-sm-6"> | ||||
|                   <label>{{ $t('expenses.amount') }}</label> <span class="text-danger"> * </span> | ||||
|                   <div class="base-input"> | ||||
|                     <money | ||||
|                       v-model="amount" | ||||
|                       v-bind="defaultCurrencyForInput" | ||||
|                       class="input-field" | ||||
|                       @input="$v.formData.amount.$touch()" | ||||
|                     /> | ||||
|                   </div> | ||||
|                   <div v-if="$v.formData.amount.$error"> | ||||
|                     <span v-if="!$v.formData.amount.required" class="text-danger">{{ $t('validation.required') }}</span> | ||||
|                     <span v-if="!$v.formData.amount.maxLength" class="text-danger">{{ $t('validation.amount_maxlength') }}</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="form-group col-sm-6"> | ||||
|                   <label for="description">{{ $t('expenses.note') }}</label> | ||||
|                   <base-text-area | ||||
|                     v-model="formData.notes" | ||||
|                     @input="$v.formData.notes.$touch()" | ||||
|                   /> | ||||
|                   <div v-if="$v.formData.notes.$error"> | ||||
|                     <span v-if="!$v.formData.notes.maxLength" class="text-danger">{{ $t('validation.notes_maxlength') }}</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="form-group col-md-6"> | ||||
|                   <label for="description">{{ $t('expenses.receipt') }} : </label> | ||||
|                   <div class="image-upload-box" @click="$refs.file.click()"> | ||||
|                     <input ref="file" class="d-none" type="file" @change="onFileChange"> | ||||
|                     <img v-if="previewReceipt" :src="previewReceipt" class="preview-logo"> | ||||
|                     <div v-else class="upload-content"> | ||||
|                       <font-awesome-icon class="upload-icon" icon="cloud-upload-alt"/> | ||||
|                       <p class="upload-text"> {{ $t('general.choose_file') }} </p> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="col-sm-12"> | ||||
|                   <div class="form-group collapse-button-container"> | ||||
|                     <base-button | ||||
|                       :loading="isLoading" | ||||
|                       icon="save" | ||||
|                       color="theme" | ||||
|                       type="submit" | ||||
|                       class="collapse-button" | ||||
|                     > | ||||
|                       {{ isEdit ? $t('expenses.update_expense') : $t('expenses.save_expense') }} | ||||
|                     </base-button> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </form> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import MultiSelect from 'vue-multiselect' | ||||
| import moment from 'moment' | ||||
| import { mapActions, mapGetters } from 'vuex' | ||||
| import { validationMixin } from 'vuelidate' | ||||
| const { required, minValue, maxLength } = require('vuelidate/lib/validators') | ||||
|  | ||||
| export default { | ||||
|   components: { | ||||
|     MultiSelect | ||||
|   }, | ||||
|   mixins: [validationMixin], | ||||
|   props: { | ||||
|     addname: { | ||||
|       type: String, | ||||
|       default: '' | ||||
|     } | ||||
|   }, | ||||
|   data () { | ||||
|     return { | ||||
|       formData: { | ||||
|         expense_category_id: null, | ||||
|         expense_date: new Date(), | ||||
|         amount: null, | ||||
|         notes: '' | ||||
|       }, | ||||
|       money: { | ||||
|         decimal: '.', | ||||
|         thousands: ',', | ||||
|         prefix: '$ ', | ||||
|         precision: 2, | ||||
|         masked: false | ||||
|       }, | ||||
|       isReceiptAvailable: false, | ||||
|       isLoading: false, | ||||
|       file: null, | ||||
|       category: null, | ||||
|       passData: [], | ||||
|       contacts: [], | ||||
|       previewReceipt: null, | ||||
|       fileSendUrl: '/api/expenses' | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
|     category: { | ||||
|       required | ||||
|     }, | ||||
|     formData: { | ||||
|       expense_date: { | ||||
|         required | ||||
|       }, | ||||
|       amount: { | ||||
|         required, | ||||
|         maxLength: maxLength(10), | ||||
|         minValue: minValue(0.1) | ||||
|       }, | ||||
|       notes: { | ||||
|         maxLength: maxLength(255) | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapGetters('currency', [ | ||||
|       'defaultCurrencyForInput' | ||||
|     ]), | ||||
|     amount: { | ||||
|       get: function () { | ||||
|         return this.formData.amount / 100 | ||||
|       }, | ||||
|       set: function (newValue) { | ||||
|         this.formData.amount = newValue * 100 | ||||
|       } | ||||
|     }, | ||||
|     isEdit () { | ||||
|       if (this.$route.name === 'expenses.edit') { | ||||
|         return true | ||||
|       } | ||||
|       return false | ||||
|     }, | ||||
|     ...mapGetters('category', [ | ||||
|       'categories' | ||||
|     ]), | ||||
|     ...mapGetters('company', [ | ||||
|       'getSelectedCompany' | ||||
|     ]), | ||||
|     getReceiptUrl () { | ||||
|       if (this.isEdit) { | ||||
|         return `/expenses/${this.$route.params.id}/receipt/${this.getSelectedCompany.unique_hash}` | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     category (newValue) { | ||||
|       this.formData.expense_category_id = newValue.id | ||||
|     } | ||||
|   }, | ||||
|   mounted () { | ||||
|     // this.$refs.baseSelect.$refs.search.focus() | ||||
|     this.fetchInitialData() | ||||
|     if (this.isEdit) { | ||||
|       this.getReceipt() | ||||
|     } | ||||
|     window.hub.$on('newCategory', (val) => { | ||||
|       this.category = val | ||||
|     }) | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('expense', [ | ||||
|       'fetchCreateExpense', | ||||
|       'getFile', | ||||
|       'sendFileWithData', | ||||
|       'addExpense', | ||||
|       'updateExpense', | ||||
|       'fetchExpense' | ||||
|     ]), | ||||
|     ...mapActions('modal', [ | ||||
|       'openModal' | ||||
|     ]), | ||||
|     ...mapActions('category', [ | ||||
|       'fetchCategories' | ||||
|     ]), | ||||
|     openCategoryModal () { | ||||
|       this.openModal({ | ||||
|         'title': 'Add Category', | ||||
|         'componentName': 'CategoryModal' | ||||
|       }) | ||||
|       // this.$refs.table.refresh() | ||||
|     }, | ||||
|     onFileChange (e) { | ||||
|       var input = event.target | ||||
|       this.file = input.files[0] | ||||
|       if (input.files && input.files[0]) { | ||||
|         var reader = new FileReader() | ||||
|         reader.onload = (e) => { | ||||
|           this.previewReceipt = e.target.result | ||||
|         } | ||||
|         reader.readAsDataURL(input.files[0]) | ||||
|       } | ||||
|     }, | ||||
|     async getReceipt () { | ||||
|       let res = await axios.get(`/api/expenses/${this.$route.params.id}/show/receipt`) | ||||
|  | ||||
|       if (res.data.error) { | ||||
|         this.isReceiptAvailable = false | ||||
|         return true | ||||
|       } | ||||
|  | ||||
|       this.isReceiptAvailable = true | ||||
|       this.previewReceipt = res.data.image | ||||
|     }, | ||||
|     async fetchInitialData () { | ||||
|       this.fetchCategories() | ||||
|       if (this.isEdit) { | ||||
|         let response = await this.fetchExpense(this.$route.params.id) | ||||
|         this.category = response.data.expense.category | ||||
|         this.formData = { ...response.data.expense } | ||||
|         this.formData.expense_date = moment(this.formData.expense_date).toString() | ||||
|         this.formData.amount = (response.data.expense.amount) | ||||
|         this.fileSendUrl = `/api/expenses/${this.$route.params.id}` | ||||
|       } | ||||
|     }, | ||||
|     async sendData () { | ||||
|       this.$v.category.$touch() | ||||
|       this.$v.formData.$touch() | ||||
|       if (this.$v.$invalid) { | ||||
|         return true | ||||
|       } | ||||
|  | ||||
|       let data = new FormData() | ||||
|  | ||||
|       if (this.file) { | ||||
|         data.append('attachment_receipt', this.file) | ||||
|       } | ||||
|       data.append('expense_category_id', this.formData.expense_category_id) | ||||
|       data.append('expense_date',  moment(this.formData.expense_date).format('DD/MM/YYYY')) | ||||
|       data.append('amount', (this.formData.amount)) | ||||
|       data.append('notes', this.formData.notes) | ||||
|  | ||||
|       if (this.isEdit) { | ||||
|         this.isLoading = true | ||||
|         data.append('_method', 'PUT') | ||||
|         let response = await this.updateExpense({id: this.$route.params.id, editData: data}) | ||||
|         if (response.data.success) { | ||||
|           window.toastr['success'](this.$t('expenses.updated_message')) | ||||
|           this.isLoading = false | ||||
|           this.$router.push('/admin/expenses') | ||||
|           return true | ||||
|         } | ||||
|         window.toastr['error'](response.data.error) | ||||
|       } else { | ||||
|         this.isLoading = true | ||||
|         let response = await this.addExpense(data) | ||||
|         if (response.data.success) { | ||||
|           window.toastr['success'](this.$t('expenses.created_message')) | ||||
|           this.isLoading = false | ||||
|           this.$router.push('/admin/expenses') | ||||
|           this.isLoading = false | ||||
|           return true | ||||
|         } | ||||
|         window.toastr['success'](response.data.success) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										398
									
								
								resources/assets/js/views/expenses/Index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										398
									
								
								resources/assets/js/views/expenses/Index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,398 @@ | ||||
| <template> | ||||
|   <div class="expenses main-content"> | ||||
|     <div class="page-header"> | ||||
|       <h3 class="page-title">{{ $t('expenses.title') }}</h3> | ||||
|       <ol class="breadcrumb"> | ||||
|         <li class="breadcrumb-item"> | ||||
|           <router-link | ||||
|             slot="item-title" | ||||
|             to="dashboard"> | ||||
|             {{ $t('general.home') }} | ||||
|           </router-link> | ||||
|         </li> | ||||
|         <li class="breadcrumb-item"> | ||||
|           <router-link | ||||
|             slot="item-title" | ||||
|             to="#"> | ||||
|             {{ $tc('expenses.expense',2) }} | ||||
|           </router-link> | ||||
|         </li> | ||||
|       </ol> | ||||
|       <div class="page-actions row"> | ||||
|         <div class="col-xs-2 mr-4"> | ||||
|           <base-button | ||||
|             v-show="totalExpenses || filtersApplied" | ||||
|             :outline="true" | ||||
|             :icon="filterIcon" | ||||
|             size="large" | ||||
|             right-icon | ||||
|             color="theme" | ||||
|             @click="toggleFilter" | ||||
|           > | ||||
|             {{ $t('general.filter') }} | ||||
|           </base-button> | ||||
|         </div> | ||||
|         <router-link slot="item-title" class="col-xs-2" to="expenses/create"> | ||||
|           <base-button size="large" icon="plus" color="theme"> | ||||
|             {{ $t('expenses.add_expense') }} | ||||
|           </base-button> | ||||
|         </router-link> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <transition name="fade"> | ||||
|       <div v-show="showFilters" class="filter-section"> | ||||
|         <div class="row"> | ||||
|           <div class="col-md-4"> | ||||
|             <label>{{ $t('expenses.category') }}</label> | ||||
|             <base-select | ||||
|               v-model="filters.category" | ||||
|               :options="categories" | ||||
|               :searchable="true" | ||||
|               :show-labels="false" | ||||
|               :placeholder="$t('expenses.categories.select_a_category')" | ||||
|               label="name" | ||||
|               @click="filter = ! filter" | ||||
|             /> | ||||
|           </div> | ||||
|           <div class="col-md-4"> | ||||
|             <label>{{ $t('expenses.from_date') }}</label> | ||||
|             <base-date-picker | ||||
|               v-model="filters.from_date" | ||||
|               :calendar-button="true" | ||||
|               calendar-button-icon="calendar" | ||||
|             /> | ||||
|           </div> | ||||
|           <div class="col-md-4"> | ||||
|             <label>{{ $t('expenses.to_date') }}</label> | ||||
|             <base-date-picker | ||||
|               v-model="filters.to_date" | ||||
|               :calendar-button="true" | ||||
|               calendar-button-icon="calendar" | ||||
|             /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <label class="clear-filter" @click="clearFilter">{{ $t('general.clear_all') }}</label> | ||||
|       </div> | ||||
|     </transition> | ||||
|  | ||||
|     <div v-cloak v-show="showEmptyScreen" class="col-xs-1 no-data-info" align="center"> | ||||
|       <observatory-icon class="mt-5 mb-4"/> | ||||
|       <div class="row" align="center"> | ||||
|         <label class="col title">{{ $t('expenses.no_expenses') }}</label> | ||||
|       </div> | ||||
|       <div class="row"> | ||||
|         <label class="description col mt-1" align="center">{{ $t('expenses.list_of_expenses') }}</label> | ||||
|       </div> | ||||
|       <div class="row"> | ||||
|         <div class="col"> | ||||
|           <base-button | ||||
|             :outline="true" | ||||
|             color="theme" | ||||
|             class="mt-3" | ||||
|             size="large" | ||||
|             @click="$router.push('expenses/create')" | ||||
|           > | ||||
|             {{ $t('expenses.add_new_expense') }} | ||||
|           </base-button> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div v-show="!showEmptyScreen" class="table-container"> | ||||
|  | ||||
|       <div class="table-actions mt-5"> | ||||
|         <p class="table-stats">{{ $t('general.showing') }}: <b>{{ expenses.length }}</b> {{ $t('general.of') }} <b>{{ totalExpenses }}</b></p> | ||||
|         <transition name="fade"> | ||||
|           <v-dropdown v-if="selectedExpenses.length" :show-arrow="false" theme-light class="action mr-5"> | ||||
|             <span slot="activator" href="#" class="table-actions-button dropdown-toggle"> | ||||
|               {{ $t('general.actions') }} | ||||
|             </span> | ||||
|             <v-dropdown-item> | ||||
|               <div class="dropdown-item" @click="removeMultipleExpenses"> | ||||
|                 <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|                 {{ $t('general.delete') }} | ||||
|               </div> | ||||
|             </v-dropdown-item> | ||||
|           </v-dropdown> | ||||
|         </transition> | ||||
|       </div> | ||||
|  | ||||
|       <div class="custom-control custom-checkbox"> | ||||
|         <input | ||||
|           id="select-all" | ||||
|           v-model="selectAllFieldStatus" | ||||
|           type="checkbox" | ||||
|           class="custom-control-input" | ||||
|           @change="selectAllExpenses" | ||||
|         > | ||||
|         <label v-show="!isRequestOngoing" for="select-all" class="custom-control-label selectall"> | ||||
|           <span class="select-all-label">{{ $t('general.select_all') }} </span> | ||||
|         </label> | ||||
|       </div> | ||||
|  | ||||
|       <table-component | ||||
|         ref="table" | ||||
|         :show-filter="false" | ||||
|         :data="fetchData" | ||||
|         table-class="table" | ||||
|       > | ||||
|  | ||||
|         <table-column | ||||
|           :sortable="false" | ||||
|           :filterable="false" | ||||
|           cell-class="no-click" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <div class="custom-control custom-checkbox"> | ||||
|               <input | ||||
|                 :id="row.id" | ||||
|                 v-model="selectField" | ||||
|                 :value="row.id" | ||||
|                 type="checkbox" | ||||
|                 class="custom-control-input" | ||||
|               > | ||||
|               <label :for="row.id" class="custom-control-label" /> | ||||
|             </div> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :label="$tc('expenses.categories.category', 1)" | ||||
|           sort-as="name" | ||||
|           show="category.name" | ||||
|         /> | ||||
|         <table-column | ||||
|           :label="$t('expenses.date')" | ||||
|           sort-as="expense_date" | ||||
|           show="formattedExpenseDate" | ||||
|         /> | ||||
|         <table-column | ||||
|           :label="$t('expenses.note')" | ||||
|           sort-as="expense_date" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <div class="notes"> | ||||
|               <div class="note">{{ row.notes }}</div> | ||||
|             </div> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :label="$t('expenses.amount')" | ||||
|           sort-as="amount" | ||||
|           show="category.amount" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('expenses.amount') }}</span> | ||||
|             <div v-html="$utils.formatMoney(row.amount, defaultCurrency)" /> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :sortable="false" | ||||
|           :filterable="false" | ||||
|           cell-class="action-dropdown no-click" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('expenses.action') }}</span> | ||||
|             <v-dropdown> | ||||
|               <a slot="activator" href="#"> | ||||
|                 <dot-icon /> | ||||
|               </a> | ||||
|               <v-dropdown-item> | ||||
|                 <router-link :to="{path: `expenses/${row.id}/edit`}" class="dropdown-item"> | ||||
|                   <font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon" /> | ||||
|                   {{ $t('general.edit') }} | ||||
|                 </router-link> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item> | ||||
|                 <div class="dropdown-item" @click="removeExpense(row.id)"> | ||||
|                   <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|                   {{ $t('general.delete') }} | ||||
|                 </div> | ||||
|               </v-dropdown-item> | ||||
|             </v-dropdown> | ||||
|           </template> | ||||
|         </table-column> | ||||
|       </table-component> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { SweetModal, SweetModalTab } from 'sweet-modal-vue' | ||||
| import { mapActions, mapGetters } from 'vuex' | ||||
| import ObservatoryIcon from '../../components/icon/ObservatoryIcon' | ||||
| import MultiSelect from 'vue-multiselect' | ||||
| import moment, { invalid } from 'moment' | ||||
|  | ||||
| export default { | ||||
|   components: { | ||||
|     MultiSelect, | ||||
|     'observatory-icon': ObservatoryIcon, | ||||
|     'SweetModal': SweetModal, | ||||
|     'SweetModalTab': SweetModalTab | ||||
|   }, | ||||
|   data () { | ||||
|     return { | ||||
|       showFilters: false, | ||||
|       filtersApplied: false, | ||||
|       isRequestOngoing: true, | ||||
|       filters: { | ||||
|         category: null, | ||||
|         from_date: '', | ||||
|         to_date: '' | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     showEmptyScreen () { | ||||
|       return !this.totalExpenses && !this.isRequestOngoing && !this.filtersApplied | ||||
|     }, | ||||
|     filterIcon () { | ||||
|       return (this.showFilters) ? 'times' : 'filter' | ||||
|     }, | ||||
|     ...mapGetters('category', [ | ||||
|       'categories' | ||||
|     ]), | ||||
|     ...mapGetters('expense', [ | ||||
|       'selectedExpenses', | ||||
|       'totalExpenses', | ||||
|       'expenses', | ||||
|       'selectAllField' | ||||
|     ]), | ||||
|     ...mapGetters('currency', [ | ||||
|       'defaultCurrency' | ||||
|     ]), | ||||
|     selectField: { | ||||
|       get: function () { | ||||
|         return this.selectedExpenses | ||||
|       }, | ||||
|       set: function (val) { | ||||
|         this.selectExpense(val) | ||||
|       } | ||||
|     }, | ||||
|     selectAllFieldStatus: { | ||||
|       get: function () { | ||||
|         return this.selectAllField | ||||
|       }, | ||||
|       set: function (val) { | ||||
|         this.setSelectAllState(val) | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     filters: { | ||||
|       handler: 'setFilters', | ||||
|       deep: true | ||||
|     } | ||||
|   }, | ||||
|   destroyed () { | ||||
|     if (this.selectAllField) { | ||||
|       this.selectAllExpenses() | ||||
|     } | ||||
|   }, | ||||
|   created () { | ||||
|     this.fetchCategories() | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('expense', [ | ||||
|       'fetchExpenses', | ||||
|       'selectExpense', | ||||
|       'deleteExpense', | ||||
|       'deleteMultipleExpenses', | ||||
|       'selectAllExpenses', | ||||
|       'setSelectAllState' | ||||
|     ]), | ||||
|     ...mapActions('category', [ | ||||
|       'fetchCategories' | ||||
|     ]), | ||||
|     async fetchData ({ page, filter, sort }) { | ||||
|       let data = { | ||||
|         expense_category_id: this.filters.category !== null ? this.filters.category.id : '', | ||||
|         from_date: this.filters.from_date === '' ? this.filters.from_date : moment(this.filters.from_date).format('DD/MM/YYYY'), | ||||
|         to_date: this.filters.to_date === '' ? this.filters.to_date : moment(this.filters.to_date).format('DD/MM/YYYY'), | ||||
|         orderByField: sort.fieldName || 'created_at', | ||||
|         orderBy: sort.order || 'desc', | ||||
|         page | ||||
|       } | ||||
|  | ||||
|       this.isRequestOngoing = true | ||||
|       let response = await this.fetchExpenses(data) | ||||
|       this.isRequestOngoing = false | ||||
|  | ||||
|       return { | ||||
|         data: response.data.expenses.data, | ||||
|         pagination: { | ||||
|           totalPages: response.data.expenses.last_page, | ||||
|           currentPage: page, | ||||
|           count: response.data.expenses.count | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     refreshTable () { | ||||
|       this.$refs.table.refresh() | ||||
|     }, | ||||
|     setFilters () { | ||||
|       this.filtersApplied = true | ||||
|       this.refreshTable() | ||||
|     }, | ||||
|     clearFilter () { | ||||
|       this.filters = { | ||||
|         category: null, | ||||
|         from_date: '', | ||||
|         to_date: '' | ||||
|       } | ||||
|  | ||||
|       this.$nextTick(() => { | ||||
|         this.filtersApplied = false | ||||
|       }) | ||||
|     }, | ||||
|     toggleFilter () { | ||||
|       if (this.showFilters && this.filtersApplied) { | ||||
|         this.clearFilter() | ||||
|         this.refreshTable() | ||||
|       } | ||||
|  | ||||
|       this.showFilters = !this.showFilters | ||||
|     }, | ||||
|     async removeExpense (id) { | ||||
|       swal({ | ||||
|         title: this.$t('general.are_you_sure'), | ||||
|         text: this.$tc('expenses.confirm_delete'), | ||||
|         icon: 'error', | ||||
|         buttons: true, | ||||
|         dangerMode: true | ||||
|       }).then(async (willDelete) => { | ||||
|         if (willDelete) { | ||||
|           let res = await this.deleteExpense(id) | ||||
|           if (res.data.success) { | ||||
|             window.toastr['success'](this.$tc('expenses.deleted_message', 1)) | ||||
|             this.$refs.table.refresh() | ||||
|             return true | ||||
|           } else if (res.data.error) { | ||||
|             window.toastr['error'](res.data.message) | ||||
|           } | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     async removeMultipleExpenses () { | ||||
|       swal({ | ||||
|         title: this.$t('general.are_you_sure'), | ||||
|         text: this.$tc('expenses.confirm_delete', 2), | ||||
|         icon: 'error', | ||||
|         buttons: true, | ||||
|         dangerMode: true | ||||
|       }).then(async (willDelete) => { | ||||
|         if (willDelete) { | ||||
|           let request = await this.deleteMultipleExpenses() | ||||
|           if (request.data.success) { | ||||
|             window.toastr['success'](this.$tc('expenses.deleted_message', 2)) | ||||
|             this.$refs.table.refresh() | ||||
|           } else if (request.data.error) { | ||||
|             window.toastr['error'](request.data.message) | ||||
|           } | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
		Reference in New Issue
	
	Block a user