mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-27 11:41:09 -04:00
v5.0.0 update
This commit is contained in:
74
resources/scripts/stores/auth.js
Normal file
74
resources/scripts/stores/auth.js
Normal file
@ -0,0 +1,74 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { useResetStore } from './reset'
|
||||
import router from '@/scripts/router'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useAuthStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
const resetStore = useResetStore()
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'auth',
|
||||
state: () => ({
|
||||
status: '',
|
||||
|
||||
loginData: {
|
||||
email: '',
|
||||
password: '',
|
||||
remember: '',
|
||||
},
|
||||
}),
|
||||
|
||||
actions: {
|
||||
login(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.get('/sanctum/csrf-cookie').then((response) => {
|
||||
if (response) {
|
||||
axios
|
||||
.post('/login', data)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
|
||||
setTimeout(() => {
|
||||
this.loginData.email = ''
|
||||
this.loginData.password = ''
|
||||
}, 1000)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
logout() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/auth/logout')
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: 'Logged out successfully.',
|
||||
})
|
||||
|
||||
router.push('/login')
|
||||
resetStore.clearPinia()
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
router.push('/')
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
76
resources/scripts/stores/backup.js
Normal file
76
resources/scripts/stores/backup.js
Normal file
@ -0,0 +1,76 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useBackupStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'backup',
|
||||
|
||||
state: () => ({
|
||||
backups: [],
|
||||
currentBackupData: {
|
||||
option: 'full',
|
||||
selected_disk: null,
|
||||
},
|
||||
}),
|
||||
|
||||
actions: {
|
||||
fetchBackups(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/backups`, { params })
|
||||
.then((response) => {
|
||||
this.backups = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
createBackup(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/backups`, data)
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.backup.created_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
removeBackup(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.delete(`/api/v1/backups/${params.disk}`, { params })
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.backup.deleted_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
128
resources/scripts/stores/category.js
Normal file
128
resources/scripts/stores/category.js
Normal file
@ -0,0 +1,128 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from '@/scripts/stores/notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useCategoryStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'category',
|
||||
|
||||
state: () => ({
|
||||
categories: [],
|
||||
currentCategory: {
|
||||
id: null,
|
||||
name: '',
|
||||
description: '',
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
isEdit: (state) => (state.currentCategory.id ? true : false),
|
||||
},
|
||||
|
||||
actions: {
|
||||
fetchCategories(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/categories`, { params })
|
||||
.then((response) => {
|
||||
this.categories = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchCategory(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/categories/${id}`)
|
||||
.then((response) => {
|
||||
this.currentCategory = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addCategory(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios
|
||||
.post('/api/v1/categories', data)
|
||||
.then((response) => {
|
||||
this.categories.push(response.data.data)
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.expense_category.created_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateCategory(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios
|
||||
.put(`/api/v1/categories/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
let pos = this.categories.findIndex(
|
||||
(category) => category.id === response.data.data.id
|
||||
)
|
||||
this.categories[pos] = data.categories
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t(
|
||||
'settings.expense_category.updated_message'
|
||||
),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteCategory(id) {
|
||||
return new Promise((resolve) => {
|
||||
axios
|
||||
.delete(`/api/v1/categories/${id}`)
|
||||
.then((response) => {
|
||||
let index = this.categories.findIndex(
|
||||
(category) => category.id === id
|
||||
)
|
||||
this.categories.splice(index, 1)
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.expense_category.deleted_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
console.error(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
189
resources/scripts/stores/company.js
Normal file
189
resources/scripts/stores/company.js
Normal file
@ -0,0 +1,189 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
import Ls from '../services/ls'
|
||||
|
||||
export const useCompanyStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'company',
|
||||
|
||||
state: () => ({
|
||||
companies: [],
|
||||
selectedCompany: null,
|
||||
selectedCompanySettings: {},
|
||||
selectedCompanyCurrency: null,
|
||||
}),
|
||||
|
||||
actions: {
|
||||
setSelectedCompany(data) {
|
||||
window.Ls.set('selectedCompany', data.id)
|
||||
this.selectedCompany = data
|
||||
},
|
||||
|
||||
fetchBasicMailConfig() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/company/mail/config')
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateCompany(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put('/api/v1/company', data)
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.company_info.updated_message'),
|
||||
})
|
||||
|
||||
this.selectedCompany = response.data.data
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateCompanyLogo(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/company/upload-logo', data)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addNewCompany(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/companies', data)
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('company_switcher.created_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchCompany(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/current-company', params)
|
||||
.then((response) => {
|
||||
Object.assign(this.companyForm, response.data.data.address)
|
||||
this.companyForm.name = response.data.data.name
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchUserCompanies() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/companies')
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchCompanySettings(settings) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/company/settings', {
|
||||
params: {
|
||||
settings,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateCompanySettings({ data, message }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/company/settings', data)
|
||||
.then((response) => {
|
||||
Object.assign(this.selectedCompanySettings, data.settings)
|
||||
|
||||
if (message) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t(message),
|
||||
})
|
||||
}
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteCompany(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/companies/delete`, data)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
setDefaultCurrency(data) {
|
||||
this.defaultCurrency = data.currency
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
211
resources/scripts/stores/custom-field.js
Normal file
211
resources/scripts/stores/custom-field.js
Normal file
@ -0,0 +1,211 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import customFieldStub from '@/scripts/stub/custom-field'
|
||||
import utilities from '../helpers/utilities'
|
||||
import { util } from 'prettier'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useCustomFieldStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'custom-field',
|
||||
|
||||
state: () => ({
|
||||
customFields: [],
|
||||
isRequestOngoing: false,
|
||||
|
||||
currentCustomField: {
|
||||
...customFieldStub,
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
isEdit() {
|
||||
return this.currentCustomField.id ? true : false
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
resetCustomFields() {
|
||||
this.customFields = []
|
||||
},
|
||||
|
||||
resetCurrentCustomField() {
|
||||
this.currentCustomField = {
|
||||
...customFieldStub,
|
||||
}
|
||||
},
|
||||
|
||||
fetchCustomFields(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/custom-fields`, { params })
|
||||
.then((response) => {
|
||||
this.customFields = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchNoteCustomFields(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.isRequestOngoing) {
|
||||
resolve({ requestOnGoing: true })
|
||||
return true
|
||||
}
|
||||
|
||||
this.isRequestOngoing = true
|
||||
|
||||
axios
|
||||
.get(`/api/v1/custom-fields`, { params })
|
||||
.then((response) => {
|
||||
this.customFields = response.data.data
|
||||
this.isRequestOngoing = false
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
this.isRequestOngoing = false
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchCustomField(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/custom-fields/${id}`)
|
||||
.then((response) => {
|
||||
this.currentCustomField = response.data.data
|
||||
|
||||
if (
|
||||
this.currentCustomField.options &&
|
||||
this.currentCustomField.options.length
|
||||
) {
|
||||
this.currentCustomField.options =
|
||||
this.currentCustomField.options.map((option) => {
|
||||
return (option = { name: option })
|
||||
})
|
||||
}
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addCustomField(params) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/custom-fields`, params)
|
||||
.then((response) => {
|
||||
let data = {
|
||||
...response.data.data,
|
||||
}
|
||||
|
||||
if (data.options) {
|
||||
data.options = data.options.map((option) => {
|
||||
return { name: option ? option : '' }
|
||||
})
|
||||
}
|
||||
|
||||
this.customFields.push(data)
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.custom_fields.added_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateCustomField(params) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/custom-fields/${params.id}`, params)
|
||||
.then((response) => {
|
||||
let data = {
|
||||
...response.data.data,
|
||||
}
|
||||
|
||||
if (data.options) {
|
||||
data.options = data.options.map((option) => {
|
||||
return { name: option ? option : '' }
|
||||
})
|
||||
}
|
||||
|
||||
let pos = this.customFields.findIndex((_f) => _f.id === data.id)
|
||||
|
||||
if (this.customFields[pos]) {
|
||||
this.customFields[pos] = data
|
||||
}
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.custom_fields.updated_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteCustomFields(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.delete(`/api/v1/custom-fields/${id}`)
|
||||
.then((response) => {
|
||||
let index = this.customFields.findIndex(
|
||||
(field) => field.id === id
|
||||
)
|
||||
|
||||
this.customFields.splice(index, 1)
|
||||
|
||||
if (response.data.error) {
|
||||
notificationStore.showNotification({
|
||||
type: 'error',
|
||||
message: global.t('settings.custom_fields.already_in_use'),
|
||||
})
|
||||
} else {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.custom_fields.deleted_message'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
// notificationStore.showNotification({
|
||||
// type: 'error',
|
||||
// message: global.t('settings.custom_fields.already_in_use'),
|
||||
// })
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
255
resources/scripts/stores/customer.js
Normal file
255
resources/scripts/stores/customer.js
Normal file
@ -0,0 +1,255 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
import { useNotificationStore } from '@/scripts/stores/notification'
|
||||
import { useGlobalStore } from '@/scripts/stores/global'
|
||||
import { useCompanyStore } from '@/scripts/stores/company'
|
||||
import addressStub from '@/scripts/stub/address.js'
|
||||
import customerStub from '@/scripts/stub/customer'
|
||||
|
||||
export const useCustomerStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'customer',
|
||||
state: () => ({
|
||||
customers: [],
|
||||
totalCustomers: 0,
|
||||
selectAllField: false,
|
||||
selectedCustomers: [],
|
||||
selectedViewCustomer: {},
|
||||
isFetchingInitialSettings: false,
|
||||
isFetchingViewData: false,
|
||||
currentCustomer: {
|
||||
...customerStub(),
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
isEdit: (state) => (state.currentCustomer.id ? true : false),
|
||||
},
|
||||
|
||||
actions: {
|
||||
resetCurrentCustomer() {
|
||||
this.currentCustomer = {
|
||||
...customerStub(),
|
||||
}
|
||||
},
|
||||
|
||||
copyAddress() {
|
||||
this.currentCustomer.shipping = {
|
||||
...this.currentCustomer.billing,
|
||||
type: 'shipping',
|
||||
}
|
||||
},
|
||||
|
||||
fetchCustomerInitialSettings(isEdit) {
|
||||
const route = useRoute()
|
||||
const globalStore = useGlobalStore()
|
||||
const companyStore = useCompanyStore()
|
||||
|
||||
this.isFetchingInitialSettings = true
|
||||
let editActions = []
|
||||
if (isEdit) {
|
||||
editActions = [this.fetchCustomer(route.params.id)]
|
||||
} else {
|
||||
this.currentCustomer.currency_id =
|
||||
companyStore.selectedCompanyCurrency.id
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
globalStore.fetchCurrencies(),
|
||||
globalStore.fetchCountries(),
|
||||
...editActions,
|
||||
])
|
||||
.then(async ([res1, res2, res3]) => {
|
||||
this.isFetchingInitialSettings = false
|
||||
})
|
||||
.catch((error) => {
|
||||
handleError(error)
|
||||
})
|
||||
},
|
||||
|
||||
fetchCustomers(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/customers`, { params })
|
||||
.then((response) => {
|
||||
this.customers = response.data.data
|
||||
this.totalCustomers = response.data.meta.customer_total_count
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchViewCustomer(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.isFetchingViewData = true
|
||||
axios
|
||||
.get(`/api/v1/customers/${params.id}/stats`, { params })
|
||||
|
||||
.then((response) => {
|
||||
this.selectedViewCustomer = {}
|
||||
Object.assign(this.selectedViewCustomer, response.data.data)
|
||||
this.setAddressStub(response.data.data)
|
||||
this.isFetchingViewData = false
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
this.isFetchingViewData = false
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchCustomer(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/customers/${id}`)
|
||||
.then((response) => {
|
||||
Object.assign(this.currentCustomer, response.data.data)
|
||||
this.setAddressStub(response.data.data)
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addCustomer(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/customers', data)
|
||||
.then((response) => {
|
||||
this.customers.push(response.data.data)
|
||||
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('customers.created_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateCustomer(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/customers/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
let pos = this.customers.findIndex(
|
||||
(customer) => customer.id === response.data.data.id
|
||||
)
|
||||
this.customers[pos] = data
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('customers.updated_message'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteCustomer(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/customers/delete`, id)
|
||||
.then((response) => {
|
||||
let index = this.customers.findIndex(
|
||||
(customer) => customer.id === id
|
||||
)
|
||||
this.customers.splice(index, 1)
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('customers.deleted_message', 1),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteMultipleCustomers() {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/customers/delete`, { ids: this.selectedCustomers })
|
||||
.then((response) => {
|
||||
this.selectedCustomers.forEach((customer) => {
|
||||
let index = this.customers.findIndex(
|
||||
(_customer) => _customer.id === customer.id
|
||||
)
|
||||
this.customers.splice(index, 1)
|
||||
})
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('customers.deleted_message', 2),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
setSelectAllState(data) {
|
||||
this.selectAllField = data
|
||||
},
|
||||
|
||||
selectCustomer(data) {
|
||||
this.selectedCustomers = data
|
||||
if (this.selectedCustomers.length === this.customers.length) {
|
||||
this.selectAllField = true
|
||||
} else {
|
||||
this.selectAllField = false
|
||||
}
|
||||
},
|
||||
|
||||
selectAllCustomers() {
|
||||
if (this.selectedCustomers.length === this.customers.length) {
|
||||
this.selectedCustomers = []
|
||||
this.selectAllField = false
|
||||
} else {
|
||||
let allCustomerIds = this.customers.map((customer) => customer.id)
|
||||
this.selectedCustomers = allCustomerIds
|
||||
this.selectAllField = true
|
||||
}
|
||||
},
|
||||
|
||||
setAddressStub(data) {
|
||||
if (!data.billing) this.currentCustomer.billing = { ...addressStub }
|
||||
if (!data.shipping) this.currentCustomer.shipping = { ...addressStub }
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
86
resources/scripts/stores/dashboard.js
Normal file
86
resources/scripts/stores/dashboard.js
Normal file
@ -0,0 +1,86 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { useGlobalStore } from '@/scripts/stores/global'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useDashboardStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'dashboard',
|
||||
|
||||
state: () => ({
|
||||
stats: {
|
||||
totalAmountDue: 0,
|
||||
totalCustomerCount: 0,
|
||||
totalInvoiceCount: 0,
|
||||
totalEstimateCount: 0,
|
||||
},
|
||||
|
||||
chartData: {
|
||||
months: [],
|
||||
invoiceTotals: [],
|
||||
expenseTotals: [],
|
||||
receiptTotals: [],
|
||||
netIncomeTotals: [],
|
||||
},
|
||||
|
||||
totalSales: null,
|
||||
totalReceipts: null,
|
||||
totalExpenses: null,
|
||||
totalNetIncome: null,
|
||||
|
||||
recentDueInvoices: [],
|
||||
recentEstimates: [],
|
||||
|
||||
isDashboardDataLoaded: false,
|
||||
}),
|
||||
|
||||
actions: {
|
||||
loadData(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/dashboard`, { params })
|
||||
.then((response) => {
|
||||
// Stats
|
||||
this.stats.totalAmountDue = response.data.total_amount_due
|
||||
this.stats.totalCustomerCount = response.data.total_customer_count
|
||||
this.stats.totalInvoiceCount = response.data.total_invoice_count
|
||||
this.stats.totalEstimateCount = response.data.total_estimate_count
|
||||
|
||||
// Dashboard Chart
|
||||
if (this.chartData && response.data.chart_data) {
|
||||
this.chartData.months = response.data.chart_data.months
|
||||
this.chartData.invoiceTotals =
|
||||
response.data.chart_data.invoice_totals
|
||||
this.chartData.expenseTotals =
|
||||
response.data.chart_data.expense_totals
|
||||
this.chartData.receiptTotals =
|
||||
response.data.chart_data.receipt_totals
|
||||
this.chartData.netIncomeTotals =
|
||||
response.data.chart_data.net_income_totals
|
||||
}
|
||||
|
||||
// Dashboard Chart Labels
|
||||
this.totalSales = response.data.total_sales
|
||||
this.totalReceipts = response.data.total_receipts
|
||||
this.totalExpenses = response.data.total_expenses
|
||||
this.totalNetIncome = response.data.total_net_income
|
||||
|
||||
// Dashboard Table Data
|
||||
this.recentDueInvoices = response.data.recent_due_invoices
|
||||
this.recentEstimates = response.data.recent_estimates
|
||||
|
||||
this.isDashboardDataLoaded = true
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
49
resources/scripts/stores/dialog.js
Normal file
49
resources/scripts/stores/dialog.js
Normal file
@ -0,0 +1,49 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useDialogStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'dialog',
|
||||
state: () => ({
|
||||
active: false,
|
||||
title: '',
|
||||
message: '',
|
||||
size: 'md',
|
||||
data: null,
|
||||
variant: 'danger', // primary || danger
|
||||
yesLabel: global.t('settings.custom_fields.yes'),
|
||||
noLabel: global.t('settings.custom_fields.no'),
|
||||
noLabel: 'No',
|
||||
resolve: null,
|
||||
hideNoButton: false,
|
||||
}),
|
||||
actions: {
|
||||
openDialog(data) {
|
||||
this.active = true
|
||||
this.title = data.title
|
||||
this.message = data.message
|
||||
this.size = data.size
|
||||
this.data = data.data
|
||||
this.variant = data.variant
|
||||
this.yesLabel = data.yesLabel
|
||||
this.noLabel = data.noLabel
|
||||
this.hideNoButton = data.hideNoButton
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.resolve = resolve
|
||||
})
|
||||
},
|
||||
closeDialog() {
|
||||
this.active = false
|
||||
|
||||
setTimeout(() => {
|
||||
this.title = ''
|
||||
this.message = ''
|
||||
this.data = null
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
183
resources/scripts/stores/disk.js
Normal file
183
resources/scripts/stores/disk.js
Normal file
@ -0,0 +1,183 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from '@/scripts/stores/notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useDiskStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'disk',
|
||||
|
||||
state: () => ({
|
||||
disks: [],
|
||||
diskDrivers: [],
|
||||
diskConfigData: null,
|
||||
selected_driver: 'local',
|
||||
|
||||
doSpaceDiskConfig: {
|
||||
name: '',
|
||||
selected_driver: 'doSpaces',
|
||||
key: '',
|
||||
secret: '',
|
||||
region: '',
|
||||
bucket: '',
|
||||
endpoint: '',
|
||||
root: '',
|
||||
},
|
||||
|
||||
dropBoxDiskConfig: {
|
||||
name: '',
|
||||
selected_driver: 'dropbox',
|
||||
token: '',
|
||||
key: '',
|
||||
secret: '',
|
||||
app: '',
|
||||
},
|
||||
|
||||
localDiskConfig: {
|
||||
name: '',
|
||||
selected_driver: 'local',
|
||||
root: '',
|
||||
},
|
||||
|
||||
s3DiskConfigData: {
|
||||
name: '',
|
||||
selected_driver: 's3',
|
||||
key: '',
|
||||
secret: '',
|
||||
region: '',
|
||||
bucket: '',
|
||||
root: '',
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
getDiskDrivers: (state) => state.diskDrivers,
|
||||
},
|
||||
|
||||
actions: {
|
||||
fetchDiskEnv(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/disks/${data.disk}`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchDisks(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/disks`, { params })
|
||||
.then((response) => {
|
||||
this.disks = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchDiskDrivers() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/disk/drivers`)
|
||||
.then((response) => {
|
||||
this.diskConfigData = response.data
|
||||
this.diskDrivers = response.data.drivers
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteFileDisk(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.delete(`/api/v1/disks/${id}`)
|
||||
.then((response) => {
|
||||
if (response.data.success) {
|
||||
let index = this.disks.findIndex(
|
||||
(category) => category.id === id
|
||||
)
|
||||
this.disks.splice(index, 1)
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.disk.deleted_message'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateDisk(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/disks/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
let pos = this.disks.findIndex(
|
||||
(disk) => disk.id === response.data.data
|
||||
)
|
||||
this.disks[pos] = data.disks
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.disk.success_set_default_disk'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
createDisk(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/disks`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.disk.success_create'),
|
||||
})
|
||||
}
|
||||
this.disks.push(response.data)
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
/* notificationStore.showNotification({
|
||||
type: 'error',
|
||||
message: global.t('settings.disk.invalid_disk_credentials'),
|
||||
}) */
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
530
resources/scripts/stores/estimate.js
Normal file
530
resources/scripts/stores/estimate.js
Normal file
@ -0,0 +1,530 @@
|
||||
import axios from 'axios'
|
||||
import moment from 'moment'
|
||||
import Guid from 'guid'
|
||||
import _ from 'lodash'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useCompanyStore } from './company'
|
||||
import { useCustomerStore } from './customer'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { useItemStore } from './item'
|
||||
import { useTaxTypeStore } from './tax-type'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
import estimateStub from '../stub/estimate'
|
||||
import estimateItemStub from '../stub/estimate-item'
|
||||
import taxStub from '../stub/tax'
|
||||
|
||||
export const useEstimateStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'estimate',
|
||||
|
||||
state: () => ({
|
||||
templates: [],
|
||||
|
||||
estimates: [],
|
||||
selectAllField: false,
|
||||
selectedEstimates: [],
|
||||
totalEstimateCount: 0,
|
||||
isFetchingInitialSettings: false,
|
||||
showExchangeRate: false,
|
||||
|
||||
newEstimate: {
|
||||
...estimateStub(),
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
getSubTotal() {
|
||||
return this.newEstimate.items.reduce(function (a, b) {
|
||||
return a + b['total']
|
||||
}, 0)
|
||||
},
|
||||
getTotalSimpleTax() {
|
||||
return _.sumBy(this.newEstimate.taxes, function (tax) {
|
||||
if (!tax.compound_tax) {
|
||||
return tax.amount
|
||||
}
|
||||
return 0
|
||||
})
|
||||
},
|
||||
|
||||
getTotalCompoundTax() {
|
||||
return _.sumBy(this.newEstimate.taxes, function (tax) {
|
||||
if (tax.compound_tax) {
|
||||
return tax.amount
|
||||
}
|
||||
return 0
|
||||
})
|
||||
},
|
||||
|
||||
getTotalTax() {
|
||||
if (
|
||||
this.newEstimate.tax_per_item === 'NO' ||
|
||||
this.newEstimate.tax_per_item === null
|
||||
) {
|
||||
return this.getTotalSimpleTax + this.getTotalCompoundTax
|
||||
}
|
||||
return _.sumBy(this.newEstimate.items, function (tax) {
|
||||
return tax.tax
|
||||
})
|
||||
},
|
||||
|
||||
getSubtotalWithDiscount() {
|
||||
return this.getSubTotal - this.newEstimate.discount_val
|
||||
},
|
||||
|
||||
getTotal() {
|
||||
return this.getSubtotalWithDiscount + this.getTotalTax
|
||||
},
|
||||
|
||||
isEdit: (state) => (state.newEstimate.id ? true : false),
|
||||
},
|
||||
|
||||
actions: {
|
||||
resetCurrentEstimate() {
|
||||
this.newEstimate = {
|
||||
...estimateStub(),
|
||||
}
|
||||
},
|
||||
|
||||
previewEstimate(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/estimates/${params.id}/send/preview`, { params })
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchEstimates(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/estimates`, { params })
|
||||
.then((response) => {
|
||||
this.estimates = response.data.data
|
||||
this.totalEstimateCount = response.data.meta.estimate_total_count
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
getNextNumber(params, setState = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/next-number?key=estimate`, { params })
|
||||
.then((response) => {
|
||||
if (setState) {
|
||||
this.newEstimate.estimate_number = response.data.nextNumber
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchEstimate(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/estimates/${id}`)
|
||||
.then((response) => {
|
||||
Object.assign(this.newEstimate, response.data.data)
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
sendEstimate(data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/estimates/${data.id}/send`, data)
|
||||
.then((response) => {
|
||||
if (!data.is_preview) {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('estimates.send_estimate_successfully'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addEstimate(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/estimates', data)
|
||||
.then((response) => {
|
||||
this.estimates = [...this.estimates, response.data.estimate]
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('estimates.created_message'),
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteEstimate(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/estimates/delete`, id)
|
||||
.then((response) => {
|
||||
let index = this.estimates.findIndex(
|
||||
(estimate) => estimate.id === id
|
||||
)
|
||||
|
||||
this.estimates.splice(index, 1)
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('estimates.deleted_message', 1),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteMultipleEstimates(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/estimates/delete`, { ids: this.selectedEstimates })
|
||||
.then((response) => {
|
||||
this.selectedEstimates.forEach((estimate) => {
|
||||
let index = this.estimates.findIndex(
|
||||
(_est) => _est.id === estimate.id
|
||||
)
|
||||
this.estimates.splice(index, 1)
|
||||
})
|
||||
this.selectedEstimates = []
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('estimates.deleted_message', 2),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateEstimate(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/estimates/${data.id}`, data)
|
||||
.then((response) => {
|
||||
let pos = this.estimates.findIndex(
|
||||
(estimate) => estimate.id === response.data.data.id
|
||||
)
|
||||
this.estimates[pos] = response.data.data
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('estimates.updated_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
markAsAccepted(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/estimates/${data.id}/status`, data)
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('estimates.marked_as_accepted_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
markAsRejected(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/estimates/${data.id}/status`, data)
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('estimates.marked_as_rejected_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
markAsSent(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/estimates/${data.id}/status`, data)
|
||||
.then((response) => {
|
||||
let pos = this.estimates.findIndex(
|
||||
(estimate) => estimate.id === data.id
|
||||
)
|
||||
if (this.estimates[pos]) {
|
||||
this.estimates[pos].status = 'SENT'
|
||||
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('estimates.mark_as_sent_successfully'),
|
||||
})
|
||||
}
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
convertToInvoice(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/estimates/${id}/convert-to-invoice`)
|
||||
.then((response) => {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('estimates.conversion_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
searchEstimate(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/estimates?${data}`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
selectEstimate(data) {
|
||||
this.selectedEstimates = data
|
||||
if (this.selectedEstimates.length === this.estimates.length) {
|
||||
this.selectAllField = true
|
||||
} else {
|
||||
this.selectAllField = false
|
||||
}
|
||||
},
|
||||
|
||||
selectAllEstimates() {
|
||||
if (this.selectedEstimates.length === this.estimates.length) {
|
||||
this.selectedEstimates = []
|
||||
this.selectAllField = false
|
||||
} else {
|
||||
let allEstimateIds = this.estimates.map((estimate) => estimate.id)
|
||||
this.selectedEstimates = allEstimateIds
|
||||
this.selectAllField = true
|
||||
}
|
||||
},
|
||||
|
||||
selectCustomer(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/customers/${id}`)
|
||||
.then((response) => {
|
||||
this.newEstimate.customer = response.data.data
|
||||
this.newEstimate.customer_id = response.data.data.id
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchEstimateTemplates(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/estimates/templates`, { params })
|
||||
.then((response) => {
|
||||
this.templates = response.data.estimateTemplates
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
setTemplate(data) {
|
||||
this.newEstimate.template_name = data
|
||||
},
|
||||
|
||||
resetSelectedCustomer() {
|
||||
this.newEstimate.customer = null
|
||||
this.newEstimate.customer_id = ''
|
||||
},
|
||||
|
||||
selectNote(data) {
|
||||
this.newEstimate.selectedNote = null
|
||||
this.newEstimate.selectedNote = data
|
||||
},
|
||||
|
||||
resetSelectedNote() {
|
||||
this.newEstimate.selectedNote = null
|
||||
},
|
||||
|
||||
addItem() {
|
||||
this.newEstimate.items.push({
|
||||
...estimateItemStub,
|
||||
id: Guid.raw(),
|
||||
taxes: [{ ...taxStub, id: Guid.raw() }],
|
||||
})
|
||||
},
|
||||
|
||||
updateItem(data) {
|
||||
Object.assign(this.newEstimate.items[data.index], { ...data })
|
||||
},
|
||||
|
||||
removeItem(index) {
|
||||
this.newEstimate.items.splice(index, 1)
|
||||
},
|
||||
|
||||
deselectItem(index) {
|
||||
this.newEstimate.items[index] = {
|
||||
...estimateItemStub,
|
||||
id: Guid.raw(),
|
||||
taxes: [{ ...taxStub, id: Guid.raw() }],
|
||||
}
|
||||
},
|
||||
|
||||
async fetchEstimateInitialSettings(isEdit) {
|
||||
const companyStore = useCompanyStore()
|
||||
const customerStore = useCustomerStore()
|
||||
const itemStore = useItemStore()
|
||||
const taxTypeStore = useTaxTypeStore()
|
||||
const route = useRoute()
|
||||
|
||||
this.isFetchingInitialSettings = true
|
||||
this.newEstimate.selectedCurrency = companyStore.selectedCompanyCurrency
|
||||
|
||||
if (route.query.customer) {
|
||||
let response = await customerStore.fetchCustomer(route.query.customer)
|
||||
this.newEstimate.customer = response.data.data
|
||||
this.newEstimate.customer_id = response.data.data.id
|
||||
}
|
||||
|
||||
let editActions = []
|
||||
|
||||
if (!isEdit) {
|
||||
this.newEstimate.tax_per_item =
|
||||
companyStore.selectedCompanySettings.tax_per_item
|
||||
this.newEstimate.discount_per_item =
|
||||
companyStore.selectedCompanySettings.discount_per_item
|
||||
this.newEstimate.estimate_date = moment().format('YYYY-MM-DD')
|
||||
this.newEstimate.expiry_date = moment()
|
||||
.add(7, 'days')
|
||||
.format('YYYY-MM-DD')
|
||||
} else {
|
||||
editActions = [this.fetchEstimate(route.params.id)]
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
itemStore.fetchItems({
|
||||
filter: {},
|
||||
orderByField: '',
|
||||
orderBy: '',
|
||||
}),
|
||||
this.resetSelectedNote(),
|
||||
this.fetchEstimateTemplates(),
|
||||
this.getNextNumber(),
|
||||
taxTypeStore.fetchTaxTypes({ limit: 'all' }),
|
||||
...editActions,
|
||||
])
|
||||
.then(async ([res1, res2, res3, res4, res5, res6, res7]) => {
|
||||
// Create
|
||||
if (!isEdit) {
|
||||
if (res4.data) {
|
||||
this.newEstimate.estimate_number = res4.data.nextNumber
|
||||
}
|
||||
|
||||
this.setTemplate(this.templates[0].name)
|
||||
}
|
||||
|
||||
this.isFetchingInitialSettings = false
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
this.isFetchingInitialSettings = false
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
249
resources/scripts/stores/exchange-rate.js
Normal file
249
resources/scripts/stores/exchange-rate.js
Normal file
@ -0,0 +1,249 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useExchangeRateStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'exchange-rate',
|
||||
|
||||
state: () => ({
|
||||
supportedCurrencies: [],
|
||||
drivers: [],
|
||||
activeUsedCurrencies: [],
|
||||
providers: [],
|
||||
currencies: null,
|
||||
currentExchangeRate: {
|
||||
id: null,
|
||||
driver: '',
|
||||
key: '',
|
||||
active: true,
|
||||
currencies: [],
|
||||
},
|
||||
currencyConverter: {
|
||||
type: '',
|
||||
url: '',
|
||||
},
|
||||
bulkCurrencies: [],
|
||||
}),
|
||||
getters: {
|
||||
isEdit: (state) => (state.currentExchangeRate.id ? true : false),
|
||||
},
|
||||
|
||||
actions: {
|
||||
fetchProviders(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/exchange-rate-providers', { params })
|
||||
.then((response) => {
|
||||
this.providers = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchDefaultProviders() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/config?key=exchange_rate_drivers`)
|
||||
.then((response) => {
|
||||
this.drivers = response.data.exchange_rate_drivers
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchProvider(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/exchange-rate-providers/${id}`)
|
||||
.then((response) => {
|
||||
this.currentExchangeRate = response.data.data
|
||||
this.currencyConverter = response.data.data.driver_config
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addProvider(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/exchange-rate-providers', data)
|
||||
.then((response) => {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.exchange_rate.created_message'),
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateProvider(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/exchange-rate-providers/${data.id}`, data)
|
||||
.then((response) => {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.exchange_rate.updated_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteExchangeRate(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.delete(`/api/v1/exchange-rate-providers/${id}`)
|
||||
.then((response) => {
|
||||
let index = this.drivers.findIndex((driver) => driver.id === id)
|
||||
this.drivers.splice(index, 1)
|
||||
if (response.data.success) {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.exchange_rate.deleted_message'),
|
||||
})
|
||||
} else {
|
||||
notificationStore.showNotification({
|
||||
type: 'error',
|
||||
message: global.t('settings.exchange_rate.error'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchCurrencies(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/supported-currencies`, { params })
|
||||
.then((response) => {
|
||||
this.supportedCurrencies = response.data.supportedCurrencies
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchActiveCurrency(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/used-currencies', { params })
|
||||
.then((response) => {
|
||||
this.activeUsedCurrencies = response.data.activeUsedCurrencies
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchBulkCurrencies() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/currencies/used')
|
||||
.then((response) => {
|
||||
this.bulkCurrencies = response.data.currencies.map((_m) => {
|
||||
_m.exchange_rate = null
|
||||
return _m
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
updateBulkExchangeRate(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/currencies/bulk-update-exchange-rate', data)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
getCurrentExchangeRate(currencyId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/currencies/${currencyId}/exchange-rate`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
getCurrencyConverterServers() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/config?key=currency_converter_servers')
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
checkForActiveProvider(currency_id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/currencies/${currency_id}/active-provider`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
238
resources/scripts/stores/expense.js
Normal file
238
resources/scripts/stores/expense.js
Normal file
@ -0,0 +1,238 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
import { useNotificationStore } from './notification'
|
||||
import expenseStub from '@/scripts/stub/expense'
|
||||
import utils from '@/scripts/helpers/utilities'
|
||||
|
||||
export const useExpenseStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'expense',
|
||||
|
||||
state: () => ({
|
||||
expenses: [],
|
||||
totalExpenses: 0,
|
||||
selectAllField: false,
|
||||
selectedExpenses: [],
|
||||
paymentModes: [],
|
||||
showExchangeRate: false,
|
||||
currentExpense: {
|
||||
...expenseStub,
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
getCurrentExpense: (state) => state.currentExpense,
|
||||
getSelectedExpenses: (state) => state.selectedExpenses,
|
||||
},
|
||||
|
||||
actions: {
|
||||
resetCurrentExpenseData() {
|
||||
this.currentExpense = {
|
||||
...expenseStub,
|
||||
}
|
||||
},
|
||||
|
||||
fetchExpenses(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/expenses`, { params })
|
||||
.then((response) => {
|
||||
this.expenses = response.data.data
|
||||
this.totalExpenses = response.data.meta.expense_total_count
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchExpense(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/expenses/${id}`)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
Object.assign(this.currentExpense, response.data.data)
|
||||
this.currentExpense.selectedCurrency = response.data.data.currency
|
||||
|
||||
if (response.data.data.attachment_receipt) {
|
||||
if (
|
||||
utils.isImageFile(
|
||||
response.data.data.attachment_receipt_meta.mime_type
|
||||
)
|
||||
) {
|
||||
this.currentExpense.receiptFiles = [
|
||||
{ image: `/expenses/${id}/receipt` },
|
||||
]
|
||||
} else {
|
||||
this.currentExpense.receiptFiles = [
|
||||
{
|
||||
type: 'document',
|
||||
name: response.data.data.attachment_receipt_meta
|
||||
.file_name,
|
||||
},
|
||||
]
|
||||
}
|
||||
} else {
|
||||
this.currentExpense.receiptFiles = []
|
||||
}
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addExpense(data) {
|
||||
const formData = utils.toFormData(data)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/expenses', formData)
|
||||
.then((response) => {
|
||||
this.expenses.push(response.data)
|
||||
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('expenses.created_message'),
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateExpense({ id, data }) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
const formData = utils.toFormData(data)
|
||||
|
||||
formData.append('_method', 'PUT')
|
||||
|
||||
return new Promise((resolve) => {
|
||||
axios.post(`/api/v1/expenses/${id}`, formData).then((response) => {
|
||||
let pos = this.expenses.findIndex(
|
||||
(expense) => expense.id === response.data.id
|
||||
)
|
||||
|
||||
this.expenses[pos] = data.expense
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('expenses.updated_message'),
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
}).catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
},
|
||||
|
||||
setSelectAllState(data) {
|
||||
this.selectAllField = data
|
||||
},
|
||||
|
||||
selectExpense(data) {
|
||||
this.selectedExpenses = data
|
||||
if (this.selectedExpenses.length === this.expenses.length) {
|
||||
this.selectAllField = true
|
||||
} else {
|
||||
this.selectAllField = false
|
||||
}
|
||||
},
|
||||
|
||||
selectAllExpenses(data) {
|
||||
if (this.selectedExpenses.length === this.expenses.length) {
|
||||
this.selectedExpenses = []
|
||||
this.selectAllField = false
|
||||
} else {
|
||||
let allExpenseIds = this.expenses.map((expense) => expense.id)
|
||||
this.selectedExpenses = allExpenseIds
|
||||
this.selectAllField = true
|
||||
}
|
||||
},
|
||||
|
||||
deleteExpense(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/expenses/delete`, id)
|
||||
.then((response) => {
|
||||
let index = this.expenses.findIndex(
|
||||
(expense) => expense.id === id
|
||||
)
|
||||
this.expenses.splice(index, 1)
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('expenses.deleted_message', 1),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteMultipleExpenses() {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/expenses/delete`, { ids: this.selectedExpenses })
|
||||
.then((response) => {
|
||||
this.selectedExpenses.forEach((expense) => {
|
||||
let index = this.expenses.findIndex(
|
||||
(_expense) => _expense.id === expense.id
|
||||
)
|
||||
this.expenses.splice(index, 1)
|
||||
})
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('expenses.deleted_message', 2),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchPaymentModes(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/payment-methods`, { params })
|
||||
.then((response) => {
|
||||
this.paymentModes = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
209
resources/scripts/stores/global.js
Normal file
209
resources/scripts/stores/global.js
Normal file
@ -0,0 +1,209 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { useCompanyStore } from './company'
|
||||
import { useUserStore } from './user'
|
||||
import axios from 'axios'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
import _ from 'lodash'
|
||||
|
||||
export const useGlobalStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'global',
|
||||
state: () => ({
|
||||
// Global Configuration
|
||||
config: null,
|
||||
|
||||
// Global Lists
|
||||
timeZones: [],
|
||||
dateFormats: [],
|
||||
currencies: [],
|
||||
countries: [],
|
||||
languages: [],
|
||||
fiscalYears: [],
|
||||
|
||||
// Menus
|
||||
mainMenu: [],
|
||||
settingMenu: [],
|
||||
|
||||
// Boolean Flags
|
||||
isAppLoaded: false,
|
||||
isSidebarOpen: false,
|
||||
areCurrenciesLoading: false,
|
||||
|
||||
downloadReport: null,
|
||||
}),
|
||||
|
||||
getters: {
|
||||
menuGroups: (state) => {
|
||||
return Object.values(_.groupBy(state.mainMenu, 'group'))
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
bootstrap() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/bootstrap')
|
||||
.then((response) => {
|
||||
const companyStore = useCompanyStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
this.mainMenu = response.data.main_menu
|
||||
this.settingMenu = response.data.setting_menu
|
||||
|
||||
this.config = response.data.config
|
||||
|
||||
// user store
|
||||
userStore.currentUser = response.data.current_user
|
||||
userStore.currentUserSettings =
|
||||
response.data.current_user_settings
|
||||
userStore.currentAbilities = response.data.current_user_abilities
|
||||
|
||||
// company store
|
||||
companyStore.companies = response.data.companies
|
||||
companyStore.selectedCompany = response.data.current_company
|
||||
companyStore.setSelectedCompany(response.data.current_company)
|
||||
companyStore.selectedCompanySettings =
|
||||
response.data.current_company_settings
|
||||
companyStore.selectedCompanyCurrency =
|
||||
response.data.current_company_currency
|
||||
|
||||
global.locale =
|
||||
response.data.current_user_settings.language || 'en'
|
||||
|
||||
this.isAppLoaded = true
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchCurrencies() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.currencies.length || this.areCurrenciesLoading) {
|
||||
resolve(this.currencies)
|
||||
} else {
|
||||
this.areCurrenciesLoading = true
|
||||
axios
|
||||
.get('/api/v1/currencies')
|
||||
.then((response) => {
|
||||
this.currencies = response.data.data.filter((currency) => {
|
||||
return (currency.name = `${currency.code} - ${currency.name}`)
|
||||
})
|
||||
this.areCurrenciesLoading = false
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
this.areCurrenciesLoading = false
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
fetchConfig(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/config`, { params })
|
||||
.then((response) => {
|
||||
if (response.data.languages) {
|
||||
this.languages = response.data.languages
|
||||
} else {
|
||||
this.fiscalYears = response.data.fiscal_years
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchDateFormats() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.dateFormats.length) {
|
||||
resolve(this.dateFormats)
|
||||
} else {
|
||||
axios
|
||||
.get('/api/v1/date/formats')
|
||||
.then((response) => {
|
||||
this.dateFormats = response.data.date_formats
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
fetchTimeZones() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.timeZones.length) {
|
||||
resolve(this.timeZones)
|
||||
} else {
|
||||
axios
|
||||
.get('/api/v1/timezones')
|
||||
.then((response) => {
|
||||
this.timeZones = response.data.time_zones
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
fetchCountries() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.countries.length) {
|
||||
resolve(this.countries)
|
||||
} else {
|
||||
axios
|
||||
.get('/api/v1/countries')
|
||||
.then((response) => {
|
||||
this.countries = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
fetchPlaceholders(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/number-placeholders`, { params })
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
setSidebarVisibility(val) {
|
||||
this.isSidebarOpen = val
|
||||
},
|
||||
|
||||
setIsAppLoaded(isAppLoaded) {
|
||||
this.isAppLoaded = isAppLoaded
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
172
resources/scripts/stores/installation.js
Normal file
172
resources/scripts/stores/installation.js
Normal file
@ -0,0 +1,172 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useCompanyStore } from './company'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useInstallationStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
const companyStore = useCompanyStore()
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'installation',
|
||||
|
||||
state: () => ({
|
||||
currentDataBaseData: {
|
||||
database_connection: 'mysql',
|
||||
database_hostname: '127.0.0.1',
|
||||
database_port: '3306',
|
||||
database_name: null,
|
||||
database_username: null,
|
||||
database_password: null,
|
||||
app_url: window.location.origin,
|
||||
},
|
||||
}),
|
||||
|
||||
actions: {
|
||||
fetchInstallationRequirements() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/installation/requirements`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchInstallationStep() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/installation/wizard-step`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addInstallationStep(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/installation/wizard-step`, data)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchInstallationPermissions() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/installation/permissions`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchInstallationDatabase(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/installation/database/config`, { params })
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addInstallationDatabase(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/installation/database/config`, data)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addInstallationFinish() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/installation/finish`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
setInstallationDomain(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/installation/set-domain`, data)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
installationLogin() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.get('/sanctum/csrf-cookie').then((response) => {
|
||||
if (response) {
|
||||
axios
|
||||
.post('/api/v1/installation/login')
|
||||
.then((response) => {
|
||||
companyStore.setSelectedCompany(response.data.company)
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
checkAutheticated() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/auth/check`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
483
resources/scripts/stores/invoice.js
Normal file
483
resources/scripts/stores/invoice.js
Normal file
@ -0,0 +1,483 @@
|
||||
import axios from 'axios'
|
||||
import moment from 'moment'
|
||||
import Guid from 'guid'
|
||||
import _ from 'lodash'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
import invoiceItemStub from '../stub/invoice-item'
|
||||
import taxStub from '../stub/tax'
|
||||
import invoiceStub from '../stub/invoice'
|
||||
|
||||
import { useNotificationStore } from './notification'
|
||||
import { useCustomerStore } from './customer'
|
||||
import { useTaxTypeStore } from './tax-type'
|
||||
import { useCompanyStore } from './company'
|
||||
import { useItemStore } from './item'
|
||||
|
||||
export const useInvoiceStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'invoice',
|
||||
state: () => ({
|
||||
templates: [],
|
||||
invoices: [],
|
||||
selectedInvoices: [],
|
||||
selectAllField: false,
|
||||
invoiceTotalCount: 0,
|
||||
showExchangeRate: false,
|
||||
isFetchingInitialSettings: false,
|
||||
isFetchingInvoice: false,
|
||||
|
||||
newInvoice: {
|
||||
...invoiceStub(),
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
getInvoice: (state) => (id) => {
|
||||
let invId = parseInt(id)
|
||||
return state.invoices.find((invoice) => invoice.id === invId)
|
||||
},
|
||||
|
||||
getSubTotal() {
|
||||
return this.newInvoice.items.reduce(function (a, b) {
|
||||
return a + b['total']
|
||||
}, 0)
|
||||
},
|
||||
|
||||
getTotalSimpleTax() {
|
||||
return _.sumBy(this.newInvoice.taxes, function (tax) {
|
||||
if (!tax.compound_tax) {
|
||||
return tax.amount
|
||||
}
|
||||
return 0
|
||||
})
|
||||
},
|
||||
|
||||
getTotalCompoundTax() {
|
||||
return _.sumBy(this.newInvoice.taxes, function (tax) {
|
||||
if (tax.compound_tax) {
|
||||
return tax.amount
|
||||
}
|
||||
return 0
|
||||
})
|
||||
},
|
||||
|
||||
getTotalTax() {
|
||||
if (
|
||||
this.newInvoice.tax_per_item === 'NO' ||
|
||||
this.newInvoice.tax_per_item === null
|
||||
) {
|
||||
return this.getTotalSimpleTax + this.getTotalCompoundTax
|
||||
}
|
||||
return _.sumBy(this.newInvoice.items, function (tax) {
|
||||
return tax.tax
|
||||
})
|
||||
},
|
||||
|
||||
getSubtotalWithDiscount() {
|
||||
return this.getSubTotal - this.newInvoice.discount_val
|
||||
},
|
||||
|
||||
getTotal() {
|
||||
return this.getSubtotalWithDiscount + this.getTotalTax
|
||||
},
|
||||
|
||||
isEdit: (state) => (state.newInvoice.id ? true : false),
|
||||
},
|
||||
|
||||
actions: {
|
||||
resetCurrentInvoice() {
|
||||
this.newInvoice = {
|
||||
...invoiceStub(),
|
||||
}
|
||||
},
|
||||
|
||||
previewInvoice(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/invoices/${params.id}/send/preview`, { params })
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchInvoices(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/invoices`, { params })
|
||||
.then((response) => {
|
||||
this.invoices = response.data.data
|
||||
this.invoiceTotalCount = response.data.meta.invoice_total_count
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchInvoice(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/invoices/${id}`)
|
||||
.then((response) => {
|
||||
Object.assign(this.newInvoice, response.data.data)
|
||||
this.newInvoice.customer = response.data.data.customer
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
sendInvoice(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/invoices/${data.id}/send`, data)
|
||||
.then((response) => {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('invoices.invoice_sent_successfully'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addInvoice(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/invoices', data)
|
||||
.then((response) => {
|
||||
this.invoices = [...this.invoices, response.data.invoice]
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('invoices.created_message'),
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteInvoice(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/invoices/delete`, id)
|
||||
.then((response) => {
|
||||
let index = this.invoices.findIndex(
|
||||
(invoice) => invoice.id === id
|
||||
)
|
||||
this.invoices.splice(index, 1)
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('invoices.deleted_message', 1),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteMultipleInvoices(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/invoices/delete`, { ids: this.selectedInvoices })
|
||||
.then((response) => {
|
||||
this.selectedInvoices.forEach((invoice) => {
|
||||
let index = this.invoices.findIndex(
|
||||
(_inv) => _inv.id === invoice.id
|
||||
)
|
||||
this.invoices.splice(index, 1)
|
||||
})
|
||||
this.selectedInvoices = []
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('invoices.deleted_message', 2),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateInvoice(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/invoices/${data.id}`, data)
|
||||
.then((response) => {
|
||||
let pos = this.invoices.findIndex(
|
||||
(invoice) => invoice.id === response.data.data.id
|
||||
)
|
||||
this.invoices[pos] = response.data.data
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('invoices.updated_message'),
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
cloneInvoice(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/invoices/${data.id}/clone`, data)
|
||||
.then((response) => {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('invoices.cloned_successfully'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
markAsSent(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/invoices/${data.id}/status`, data)
|
||||
.then((response) => {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('invoices.mark_as_sent_successfully'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
getNextNumber(params, setState = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/next-number?key=invoice`, { params })
|
||||
.then((response) => {
|
||||
if (setState) {
|
||||
this.newInvoice.invoice_number = response.data.nextNumber
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
searchInvoice(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/invoices?${data}`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
selectInvoice(data) {
|
||||
this.selectedInvoices = data
|
||||
if (this.selectedInvoices.length === this.invoices.length) {
|
||||
this.selectAllField = true
|
||||
} else {
|
||||
this.selectAllField = false
|
||||
}
|
||||
},
|
||||
|
||||
selectAllInvoices() {
|
||||
if (this.selectedInvoices.length === this.invoices.length) {
|
||||
this.selectedInvoices = []
|
||||
this.selectAllField = false
|
||||
} else {
|
||||
let allInvoiceIds = this.invoices.map((invoice) => invoice.id)
|
||||
this.selectedInvoices = allInvoiceIds
|
||||
this.selectAllField = true
|
||||
}
|
||||
},
|
||||
|
||||
selectCustomer(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/customers/${id}`)
|
||||
.then((response) => {
|
||||
this.newInvoice.customer = response.data.data
|
||||
this.newInvoice.customer_id = response.data.data.id
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchInvoiceTemplates(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/invoices/templates`, { params })
|
||||
.then((response) => {
|
||||
this.templates = response.data.invoiceTemplates
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
selectNote(data) {
|
||||
this.newInvoice.selectedNote = null
|
||||
this.newInvoice.selectedNote = data
|
||||
},
|
||||
|
||||
setTemplate(data) {
|
||||
this.newInvoice.template_name = data
|
||||
},
|
||||
|
||||
resetSelectedCustomer() {
|
||||
this.newInvoice.customer = null
|
||||
this.newInvoice.customer_id = null
|
||||
},
|
||||
|
||||
addItem() {
|
||||
this.newInvoice.items.push({
|
||||
...invoiceItemStub,
|
||||
id: Guid.raw(),
|
||||
taxes: [{ ...taxStub, id: Guid.raw() }],
|
||||
})
|
||||
},
|
||||
|
||||
updateItem(data) {
|
||||
Object.assign(this.newInvoice.items[data.index], { ...data })
|
||||
},
|
||||
|
||||
removeItem(index) {
|
||||
this.newInvoice.items.splice(index, 1)
|
||||
},
|
||||
|
||||
deselectItem(index) {
|
||||
this.newInvoice.items[index] = {
|
||||
...invoiceItemStub,
|
||||
id: Guid.raw(),
|
||||
taxes: [{ ...taxStub, id: Guid.raw() }],
|
||||
}
|
||||
},
|
||||
|
||||
resetSelectedNote() {
|
||||
this.newInvoice.selectedNote = null
|
||||
},
|
||||
|
||||
// On Load actions
|
||||
async fetchInvoiceInitialSettings(isEdit) {
|
||||
const companyStore = useCompanyStore()
|
||||
const customerStore = useCustomerStore()
|
||||
const itemStore = useItemStore()
|
||||
const taxTypeStore = useTaxTypeStore()
|
||||
const route = useRoute()
|
||||
|
||||
this.isFetchingInitialSettings = true
|
||||
|
||||
this.newInvoice.selectedCurrency = companyStore.selectedCompanyCurrency
|
||||
|
||||
if (route.query.customer) {
|
||||
let response = await customerStore.fetchCustomer(route.query.customer)
|
||||
this.newInvoice.customer = response.data.data
|
||||
this.newInvoice.customer_id = response.data.data.id
|
||||
}
|
||||
|
||||
let editActions = []
|
||||
|
||||
if (!isEdit) {
|
||||
this.newInvoice.tax_per_item =
|
||||
companyStore.selectedCompanySettings.tax_per_item
|
||||
this.newInvoice.discount_per_item =
|
||||
companyStore.selectedCompanySettings.discount_per_item
|
||||
this.newInvoice.invoice_date = moment().format('YYYY-MM-DD')
|
||||
this.newInvoice.due_date = moment()
|
||||
.add(7, 'days')
|
||||
.format('YYYY-MM-DD')
|
||||
} else {
|
||||
editActions = [this.fetchInvoice(route.params.id)]
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
itemStore.fetchItems({
|
||||
filter: {},
|
||||
orderByField: '',
|
||||
orderBy: '',
|
||||
}),
|
||||
this.resetSelectedNote(),
|
||||
this.fetchInvoiceTemplates(),
|
||||
this.getNextNumber(),
|
||||
taxTypeStore.fetchTaxTypes({ limit: 'all' }),
|
||||
...editActions,
|
||||
])
|
||||
.then(async ([res1, res2, res3, res4, res5, res6]) => {
|
||||
if (!isEdit) {
|
||||
if (res4.data) {
|
||||
this.newInvoice.invoice_number = res4.data.nextNumber
|
||||
}
|
||||
|
||||
if (res3.data) {
|
||||
this.setTemplate(this.templates[0].name)
|
||||
}
|
||||
}
|
||||
|
||||
this.isFetchingInitialSettings = false
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
336
resources/scripts/stores/item.js
Normal file
336
resources/scripts/stores/item.js
Normal file
@ -0,0 +1,336 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useItemStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'item',
|
||||
state: () => ({
|
||||
items: [],
|
||||
totalItems: 0,
|
||||
selectAllField: false,
|
||||
selectedItems: [],
|
||||
itemUnits: [],
|
||||
currentItemUnit: {
|
||||
id: null,
|
||||
name: '',
|
||||
},
|
||||
currentItem: {
|
||||
name: '',
|
||||
description: '',
|
||||
price: 0,
|
||||
unit_id: '',
|
||||
unit: null,
|
||||
taxes: [],
|
||||
tax_per_item: false,
|
||||
},
|
||||
}),
|
||||
getters: {
|
||||
isItemUnitEdit: (state) => (state.currentItemUnit.id ? true : false),
|
||||
},
|
||||
actions: {
|
||||
resetCurrentItem() {
|
||||
this.currentItem = {
|
||||
name: '',
|
||||
description: '',
|
||||
price: 0,
|
||||
unit_id: '',
|
||||
unit: null,
|
||||
taxes: [],
|
||||
}
|
||||
},
|
||||
fetchItems(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/items`, { params })
|
||||
.then((response) => {
|
||||
this.items = response.data.data
|
||||
this.totalItems = response.data.meta.item_total_count
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchItem(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/items/${id}`)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
Object.assign(this.currentItem, response.data.data)
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addItem(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/items', data)
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
this.items.push(response.data.data)
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('items.created_message'),
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateItem(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/items/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
let pos = this.items.findIndex(
|
||||
(item) => item.id === response.data.data.id
|
||||
)
|
||||
|
||||
this.items[pos] = data.item
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('items.updated_message'),
|
||||
})
|
||||
}
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteItem(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/items/delete`, id)
|
||||
.then((response) => {
|
||||
let index = this.items.findIndex((item) => item.id === id)
|
||||
this.items.splice(index, 1)
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('items.deleted_message', 1),
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteMultipleItems() {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/items/delete`, { ids: this.selectedItems })
|
||||
.then((response) => {
|
||||
this.selectedItems.forEach((item) => {
|
||||
let index = this.items.findIndex(
|
||||
(_item) => _item.id === item.id
|
||||
)
|
||||
this.items.splice(index, 1)
|
||||
})
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('items.deleted_message', 2),
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
selectItem(data) {
|
||||
this.selectedItems = data
|
||||
if (this.selectedItems.length === this.items.length) {
|
||||
this.selectAllField = true
|
||||
} else {
|
||||
this.selectAllField = false
|
||||
}
|
||||
},
|
||||
|
||||
selectAllItems(data) {
|
||||
if (this.selectedItems.length === this.items.length) {
|
||||
this.selectedItems = []
|
||||
this.selectAllField = false
|
||||
} else {
|
||||
let allItemIds = this.items.map((item) => item.id)
|
||||
this.selectedItems = allItemIds
|
||||
this.selectAllField = true
|
||||
}
|
||||
},
|
||||
|
||||
addItemUnit(data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/units`, data)
|
||||
.then((response) => {
|
||||
this.itemUnits.push(response.data.data)
|
||||
|
||||
if (response.data.data) {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t(
|
||||
'settings.customization.items.item_unit_added'
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
if (response.data.errors) {
|
||||
notificationStore.showNotification({
|
||||
type: 'error',
|
||||
message: err.response.data.errors[0],
|
||||
})
|
||||
}
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateItemUnit(data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/units/${data.id}`, data)
|
||||
.then((response) => {
|
||||
let pos = this.itemUnits.findIndex(
|
||||
(unit) => unit.id === response.data.data.id
|
||||
)
|
||||
|
||||
this.itemUnits[pos] = data
|
||||
|
||||
if (response.data.data) {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t(
|
||||
'settings.customization.items.item_unit_updated'
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
if (response.data.errors) {
|
||||
notificationStore.showNotification({
|
||||
type: 'error',
|
||||
message: err.response.data.errors[0],
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchItemUnits(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/units`, { params })
|
||||
.then((response) => {
|
||||
this.itemUnits = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchItemUnit(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/units/${id}`)
|
||||
.then((response) => {
|
||||
this.currentItemUnit = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteItemUnit(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.delete(`/api/v1/units/${id}`)
|
||||
.then((response) => {
|
||||
if (!response.data.error) {
|
||||
let index = this.itemUnits.findIndex((unit) => unit.id === id)
|
||||
this.itemUnits.splice(index, 1)
|
||||
}
|
||||
|
||||
if (response.data.success) {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t(
|
||||
'settings.customization.items.deleted_message'
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
146
resources/scripts/stores/mail-driver.js
Normal file
146
resources/scripts/stores/mail-driver.js
Normal file
@ -0,0 +1,146 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useMailDriverStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'mail-driver',
|
||||
|
||||
state: () => ({
|
||||
mailConfigData: null,
|
||||
mail_driver: 'smtp',
|
||||
mail_drivers: [],
|
||||
|
||||
basicMailConfig: {
|
||||
mail_driver: '',
|
||||
mail_host: '',
|
||||
from_mail: '',
|
||||
from_name: '',
|
||||
},
|
||||
|
||||
mailgunConfig: {
|
||||
mail_driver: '',
|
||||
mail_mailgun_domain: '',
|
||||
mail_mailgun_secret: '',
|
||||
mail_mailgun_endpoint: '',
|
||||
from_mail: '',
|
||||
from_name: '',
|
||||
},
|
||||
|
||||
sesConfig: {
|
||||
mail_driver: '',
|
||||
mail_host: '',
|
||||
mail_port: null,
|
||||
mail_ses_key: '',
|
||||
mail_ses_secret: '',
|
||||
mail_encryption: 'tls',
|
||||
from_mail: '',
|
||||
from_name: '',
|
||||
},
|
||||
|
||||
smtpConfig: {
|
||||
mail_driver: '',
|
||||
mail_host: '',
|
||||
mail_port: null,
|
||||
mail_username: '',
|
||||
mail_password: '',
|
||||
mail_encryption: 'tls',
|
||||
from_mail: '',
|
||||
from_name: '',
|
||||
},
|
||||
}),
|
||||
|
||||
actions: {
|
||||
fetchMailDrivers() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/mail/drivers')
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
this.mail_drivers = response.data
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchMailConfig() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/mail/config')
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
this.mailConfigData = response.data
|
||||
this.mail_driver = response.data.mail_driver
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateMailConfig(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/mail/config', data)
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
if (response.data.success) {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('wizard.success.' + response.data.success),
|
||||
})
|
||||
} else {
|
||||
notificationStore.showNotification({
|
||||
type: 'error',
|
||||
message: global.t('wizard.errors.' + response.data.error),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
sendTestMail(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/mail/test', data)
|
||||
.then((response) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
if (response.data.success) {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('general.send_mail_successfully'),
|
||||
})
|
||||
} else {
|
||||
notificationStore.showNotification({
|
||||
type: 'error',
|
||||
message: global.t('validation.something_went_wrong'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
74
resources/scripts/stores/modal.js
Normal file
74
resources/scripts/stores/modal.js
Normal file
@ -0,0 +1,74 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useModalStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'modal',
|
||||
|
||||
state: () => ({
|
||||
active: false,
|
||||
content: '',
|
||||
title: '',
|
||||
componentName: '',
|
||||
id: '',
|
||||
size: 'md',
|
||||
data: null,
|
||||
refreshData: null,
|
||||
variant: '',
|
||||
}),
|
||||
|
||||
getters: {
|
||||
isEdit() {
|
||||
return (this.id ? true : false)
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
openModal(payload) {
|
||||
this.componentName = payload.componentName
|
||||
this.active = true
|
||||
|
||||
if (payload.id) {
|
||||
this.id = payload.id
|
||||
}
|
||||
|
||||
this.title = payload.title
|
||||
|
||||
if (payload.data) {
|
||||
this.data = payload.data
|
||||
}
|
||||
|
||||
if (payload.refreshData) {
|
||||
this.refreshData = payload.refreshData
|
||||
}
|
||||
|
||||
if (payload.variant) {
|
||||
this.variant = payload.variant
|
||||
}
|
||||
|
||||
if (payload.size) {
|
||||
this.size = payload.size
|
||||
}
|
||||
},
|
||||
|
||||
resetModalData() {
|
||||
this.content = ''
|
||||
this.title = ''
|
||||
this.componentName = ''
|
||||
this.id = ''
|
||||
this.data = null
|
||||
this.refreshData = null
|
||||
},
|
||||
|
||||
closeModal() {
|
||||
this.active = false
|
||||
|
||||
setTimeout(() => {
|
||||
this.resetModalData()
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
})()
|
||||
}
|
||||
117
resources/scripts/stores/note.js
Normal file
117
resources/scripts/stores/note.js
Normal file
@ -0,0 +1,117 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useNotesStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'notes',
|
||||
|
||||
state: () => ({
|
||||
notes: [],
|
||||
currentNote: {
|
||||
id: null,
|
||||
type: '',
|
||||
name: '',
|
||||
notes: '',
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
isEdit: (state) => (state.currentNote.id ? true : false),
|
||||
},
|
||||
|
||||
actions: {
|
||||
resetCurrentNote() {
|
||||
this.currentNote = {
|
||||
type: '',
|
||||
name: '',
|
||||
notes: '',
|
||||
}
|
||||
},
|
||||
|
||||
fetchNotes(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/notes`, { params })
|
||||
.then((response) => {
|
||||
this.notes = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchNote(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/notes/${id}`)
|
||||
.then((response) => {
|
||||
this.currentNote = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addNote(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/notes', data)
|
||||
.then((response) => {
|
||||
this.notes.push(response.data)
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateNote(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/notes/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
let pos = this.notes.findIndex(
|
||||
(notes) => notes.id === response.data.data.id
|
||||
)
|
||||
this.notes[pos] = data.notes
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteNote(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.delete(`/api/v1/notes/${id}`)
|
||||
.then((response) => {
|
||||
let index = this.notes.findIndex((note) => note.id === id)
|
||||
this.notes.splice(index, 1)
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
30
resources/scripts/stores/notification.js
Normal file
30
resources/scripts/stores/notification.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useNotificationStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'notification',
|
||||
|
||||
state: () => ({
|
||||
active: false,
|
||||
autoHide: true,
|
||||
notifications: [],
|
||||
}),
|
||||
|
||||
actions: {
|
||||
showNotification(notification) {
|
||||
this.notifications.push({
|
||||
...notification,
|
||||
id: (Math.random().toString(36) + Date.now().toString(36)).substr(2),
|
||||
})
|
||||
},
|
||||
|
||||
hideNotification(data) {
|
||||
this.notifications = this.notifications.filter((notification) => {
|
||||
return notification.id != data.id
|
||||
})
|
||||
}
|
||||
}
|
||||
})()
|
||||
}
|
||||
410
resources/scripts/stores/payment.js
Normal file
410
resources/scripts/stores/payment.js
Normal file
@ -0,0 +1,410 @@
|
||||
import axios from 'axios'
|
||||
import moment from 'moment'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useCompanyStore } from './company'
|
||||
import { useNotificationStore } from './notification'
|
||||
import paymentStub from '../stub/payment'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const usePaymentStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'payment',
|
||||
|
||||
state: () => ({
|
||||
payments: [],
|
||||
paymentTotalCount: 0,
|
||||
|
||||
selectAllField: false,
|
||||
selectedPayments: [],
|
||||
selectedNote: null,
|
||||
showExchangeRate: false,
|
||||
|
||||
currentPayment: {
|
||||
...paymentStub,
|
||||
},
|
||||
|
||||
paymentModes: [],
|
||||
currentPaymentMode: {
|
||||
id: '',
|
||||
name: null,
|
||||
},
|
||||
|
||||
isFetchingInitialData: false,
|
||||
}),
|
||||
|
||||
actions: {
|
||||
fetchPaymentInitialData(isEdit) {
|
||||
const companyStore = useCompanyStore()
|
||||
const route = useRoute()
|
||||
|
||||
this.isFetchingInitialData = true
|
||||
|
||||
let actions = []
|
||||
if (isEdit) {
|
||||
actions = [this.fetchPayment(route.params.id)]
|
||||
}
|
||||
Promise.all([
|
||||
this.fetchPaymentModes({ limit: 'all' }),
|
||||
this.getNextNumber(),
|
||||
...actions,
|
||||
])
|
||||
.then(async ([res1, res2, res3]) => {
|
||||
if (isEdit) {
|
||||
if (res3.data.data.invoice) {
|
||||
this.currentPayment.maxPayableAmount = parseInt(
|
||||
res3.data.data.invoice.due_amount
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// On Create
|
||||
else if (!isEdit && res2.data) {
|
||||
this.currentPayment.payment_date = moment().format('YYYY-MM-DD')
|
||||
this.currentPayment.payment_number = res2.data.nextNumber
|
||||
this.currentPayment.currency =
|
||||
companyStore.selectedCompanyCurrency
|
||||
}
|
||||
|
||||
this.isFetchingInitialData = false
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
})
|
||||
},
|
||||
|
||||
fetchPayments(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/payments`, { params })
|
||||
.then((response) => {
|
||||
this.payments = response.data.data
|
||||
this.paymentTotalCount = response.data.meta.payment_total_count
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchPayment(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/payments/${id}`)
|
||||
.then((response) => {
|
||||
Object.assign(this.currentPayment, response.data.data)
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
addPayment(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/payments', data)
|
||||
.then((response) => {
|
||||
this.payments.push(response.data)
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('payments.created_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updatePayment(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/payments/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
let pos = this.payments.findIndex(
|
||||
(payment) => payment.id === response.data.data.id
|
||||
)
|
||||
|
||||
this.payments[pos] = data.payment
|
||||
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('payments.updated_message'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deletePayment(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/payments/delete`, id)
|
||||
.then((response) => {
|
||||
let index = this.payments.findIndex(
|
||||
(payment) => payment.id === id
|
||||
)
|
||||
this.payments.splice(index, 1)
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('payments.deleted_message', 1),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteMultiplePayments() {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/payments/delete`, { ids: this.selectedPayments })
|
||||
.then((response) => {
|
||||
this.selectedPayments.forEach((payment) => {
|
||||
let index = this.payments.findIndex(
|
||||
(_payment) => _payment.id === payment.id
|
||||
)
|
||||
this.payments.splice(index, 1)
|
||||
})
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('payments.deleted_message', 2),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
setSelectAllState(data) {
|
||||
this.selectAllField = data
|
||||
},
|
||||
|
||||
selectPayment(data) {
|
||||
this.selectedPayments = data
|
||||
if (this.selectedPayments.length === this.payments.length) {
|
||||
this.selectAllField = true
|
||||
} else {
|
||||
this.selectAllField = false
|
||||
}
|
||||
},
|
||||
|
||||
selectAllPayments() {
|
||||
if (this.selectedPayments.length === this.payments.length) {
|
||||
this.selectedPayments = []
|
||||
this.selectAllField = false
|
||||
} else {
|
||||
let allPaymentIds = this.payments.map((payment) => payment.id)
|
||||
this.selectedPayments = allPaymentIds
|
||||
this.selectAllField = true
|
||||
}
|
||||
},
|
||||
|
||||
selectNote(data) {
|
||||
this.selectedNote = null
|
||||
this.selectedNote = data
|
||||
},
|
||||
|
||||
resetSelectedNote(data) {
|
||||
this.selectedNote = null
|
||||
},
|
||||
|
||||
searchPayment(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/payments`, { params })
|
||||
.then((response) => {
|
||||
this.payments = response.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
previewPayment(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/payments/${params.id}/send/preview`, { params })
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
sendEmail(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/payments/${data.id}/send`, data)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
getNextNumber(params, setState = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios
|
||||
.get(`/api/v1/next-number?key=payment`, { params })
|
||||
.then((response) => {
|
||||
if (setState) {
|
||||
this.currentPayment.payment_number = response.data.nextNumber
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
resetCurrentPayment() {
|
||||
this.currentPayment = {
|
||||
...paymentStub,
|
||||
}
|
||||
},
|
||||
|
||||
fetchPaymentModes(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/payment-methods`, { params })
|
||||
.then((response) => {
|
||||
this.paymentModes = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchPaymentMode(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/payment-methods/${id}`)
|
||||
.then((response) => {
|
||||
this.currentPaymentMode = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addPaymentMode(data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/payment-methods`, data)
|
||||
.then((response) => {
|
||||
this.paymentModes.push(response.data.data)
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.payment_modes.payment_mode_added'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updatePaymentMode(data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/payment-methods/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
let pos = this.paymentModes.findIndex(
|
||||
(paymentMode) => paymentMode.id === response.data.data.id
|
||||
)
|
||||
this.paymentModes[pos] = data.paymentModes
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t(
|
||||
'settings.payment_modes.payment_mode_updated'
|
||||
),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deletePaymentMode(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.delete(`/api/v1/payment-methods/${id}`)
|
||||
.then((response) => {
|
||||
let index = this.paymentModes.findIndex(
|
||||
(paymentMode) => paymentMode.id === id
|
||||
)
|
||||
this.paymentModes.splice(index, 1)
|
||||
if (response.data.success) {
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.payment_modes.deleted_message'),
|
||||
})
|
||||
}
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
436
resources/scripts/stores/recurring-invoice.js
Normal file
436
resources/scripts/stores/recurring-invoice.js
Normal file
@ -0,0 +1,436 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import recurringInvoiceStub from '@/scripts/stub/recurring-invoice'
|
||||
import recurringInvoiceItemStub from '@/scripts/stub/recurring-invoice-item'
|
||||
import TaxStub from '../stub/tax'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useCompanyStore } from './company'
|
||||
import { useItemStore } from './item'
|
||||
import { useTaxTypeStore } from './tax-type'
|
||||
import { useCustomerStore } from './customer'
|
||||
import Guid from 'guid'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
import moment from 'moment'
|
||||
import _ from 'lodash'
|
||||
import { useInvoiceStore } from './invoice'
|
||||
import { useNotificationStore } from './notification'
|
||||
|
||||
export const useRecurringInvoiceStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'recurring-invoice',
|
||||
|
||||
state: () => ({
|
||||
templates: [],
|
||||
recurringInvoices: [],
|
||||
selectedRecurringInvoices: [],
|
||||
totalRecurringInvoices: 0,
|
||||
isFetchingInitialSettings: false,
|
||||
isFetchingViewData: false,
|
||||
showExchangeRate: false,
|
||||
selectAllField: false,
|
||||
newRecurringInvoice: {
|
||||
...recurringInvoiceStub(),
|
||||
},
|
||||
|
||||
frequencies: [
|
||||
{ label: 'Every Minute', value: '* * * * *' },
|
||||
{ label: 'Every 30 Minute', value: '*/30 * * * *' },
|
||||
{ label: 'Every Hour', value: '0 * * * *' },
|
||||
{ label: 'Every 2 Hour', value: '0 */2 * * *' },
|
||||
{ label: 'Twice A Day', value: '0 13-15 * * *' },
|
||||
{ label: 'Every Week', value: '0 0 * * 0' },
|
||||
{ label: 'Every 15 Days', value: '0 5 */15 * *' },
|
||||
{ label: 'First Day Of Month', value: '0 0 1 * *' },
|
||||
{ label: 'Every 6 Month', value: '0 0 1 */6 *' },
|
||||
{ label: 'Every Year', value: '0 0 1 1 *' },
|
||||
{ label: 'Custom', value: 'CUSTOM' },
|
||||
],
|
||||
}),
|
||||
|
||||
getters: {
|
||||
getSubTotal() {
|
||||
return (
|
||||
this.newRecurringInvoice?.items.reduce(function (a, b) {
|
||||
return a + b['total']
|
||||
}, 0) || 0
|
||||
)
|
||||
},
|
||||
|
||||
getTotalSimpleTax() {
|
||||
return _.sumBy(this.newRecurringInvoice.taxes, function (tax) {
|
||||
if (!tax.compound_tax) {
|
||||
return tax.amount
|
||||
}
|
||||
return 0
|
||||
})
|
||||
},
|
||||
|
||||
getTotalCompoundTax() {
|
||||
return _.sumBy(this.newRecurringInvoice.taxes, function (tax) {
|
||||
if (tax.compound_tax) {
|
||||
return tax.amount
|
||||
}
|
||||
return 0
|
||||
})
|
||||
},
|
||||
|
||||
getTotalTax() {
|
||||
if (
|
||||
this.newRecurringInvoice.tax_per_item === 'NO' ||
|
||||
this.newRecurringInvoice.tax_per_item === null
|
||||
) {
|
||||
return this.getTotalSimpleTax + this.getTotalCompoundTax
|
||||
}
|
||||
return _.sumBy(this.newRecurringInvoice.items, function (tax) {
|
||||
return tax.tax
|
||||
})
|
||||
},
|
||||
|
||||
getSubtotalWithDiscount() {
|
||||
return this.getSubTotal - this.newRecurringInvoice.discount_val
|
||||
},
|
||||
|
||||
getTotal() {
|
||||
return this.getSubtotalWithDiscount + this.getTotalTax
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
resetCurrentRecurringInvoice() {
|
||||
this.newRecurringInvoice = {
|
||||
...recurringInvoiceStub(),
|
||||
}
|
||||
},
|
||||
|
||||
deselectItem(index) {
|
||||
this.newRecurringInvoice.items[index] = {
|
||||
...recurringInvoiceItemStub,
|
||||
id: Guid.raw(),
|
||||
taxes: [{ ...TaxStub, id: Guid.raw() }],
|
||||
}
|
||||
},
|
||||
|
||||
addRecurringInvoice(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/recurring-invoices', data)
|
||||
.then((response) => {
|
||||
this.recurringInvoices = [
|
||||
...this.recurringInvoices,
|
||||
response.data.recurringInvoice,
|
||||
]
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('recurring_invoices.created_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchRecurringInvoice(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.isFetchingViewData = true
|
||||
axios
|
||||
.get(`/api/v1/recurring-invoices/${id}`)
|
||||
.then((response) => {
|
||||
Object.assign(this.newRecurringInvoice, response.data.data)
|
||||
this.newRecurringInvoice.invoices =
|
||||
response.data.data.invoices || []
|
||||
this.setSelectedFrequency()
|
||||
this.isFetchingViewData = false
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
this.isFetchingViewData = false
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateRecurringInvoice(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/recurring-invoices/${data.id}`, data)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('recurring_invoices.updated_message'),
|
||||
})
|
||||
|
||||
let pos = this.recurringInvoices.findIndex(
|
||||
(invoice) => invoice.id === response.data.data.id
|
||||
)
|
||||
|
||||
this.recurringInvoices[pos] = response.data.data
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
selectCustomer(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/customers/${id}`)
|
||||
.then((response) => {
|
||||
this.newRecurringInvoice.customer = response.data.data
|
||||
this.newRecurringInvoice.customer_id = response.data.data.id
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
searchRecurringInvoice(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/recurring-invoices?${data}`)
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchRecurringInvoices(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/recurring-invoices`, { params })
|
||||
.then((response) => {
|
||||
this.recurringInvoices = response.data.data
|
||||
this.totalRecurringInvoices =
|
||||
response.data.meta.recurring_invoice_total_count
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteRecurringInvoice(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/recurring-invoices/delete`, id)
|
||||
.then((response) => {
|
||||
let index = this.recurringInvoices.findIndex(
|
||||
(invoice) => invoice.id === id
|
||||
)
|
||||
this.recurringInvoices.splice(index, 1)
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteMultipleRecurringInvoices(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let ids = this.selectedRecurringInvoices
|
||||
if (id) {
|
||||
ids = [id]
|
||||
}
|
||||
axios
|
||||
.post(`/api/v1/recurring-invoices/delete`, {
|
||||
ids: ids,
|
||||
})
|
||||
.then((response) => {
|
||||
this.selectedRecurringInvoices.forEach((invoice) => {
|
||||
let index = this.recurringInvoices.findIndex(
|
||||
(_inv) => _inv.id === invoice.id
|
||||
)
|
||||
this.recurringInvoices.splice(index, 1)
|
||||
})
|
||||
this.selectedRecurringInvoices = []
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
resetSelectedCustomer() {
|
||||
this.newRecurringInvoice.customer = null
|
||||
this.newRecurringInvoice.customer_id = ''
|
||||
},
|
||||
|
||||
selectRecurringInvoice(data) {
|
||||
this.selectedRecurringInvoices = data
|
||||
if (
|
||||
this.selectedRecurringInvoices.length ===
|
||||
this.recurringInvoices.length
|
||||
) {
|
||||
this.selectAllField = true
|
||||
} else {
|
||||
this.selectAllField = false
|
||||
}
|
||||
},
|
||||
|
||||
selectAllRecurringInvoices() {
|
||||
if (
|
||||
this.selectedRecurringInvoices.length ===
|
||||
this.recurringInvoices.length
|
||||
) {
|
||||
this.selectedRecurringInvoices = []
|
||||
this.selectAllField = false
|
||||
} else {
|
||||
let allInvoiceIds = this.recurringInvoices.map(
|
||||
(invoice) => invoice.id
|
||||
)
|
||||
this.selectedRecurringInvoices = allInvoiceIds
|
||||
this.selectAllField = true
|
||||
}
|
||||
},
|
||||
|
||||
addItem() {
|
||||
this.newRecurringInvoice.items.push({
|
||||
...recurringInvoiceItemStub,
|
||||
id: Guid.raw(),
|
||||
taxes: [{ ...TaxStub, id: Guid.raw() }],
|
||||
})
|
||||
},
|
||||
|
||||
removeItem(index) {
|
||||
this.newRecurringInvoice.items.splice(index, 1)
|
||||
},
|
||||
|
||||
updateItem(data) {
|
||||
Object.assign(this.newRecurringInvoice.items[data.index], { ...data })
|
||||
},
|
||||
|
||||
async fetchRecurringInvoiceInitialSettings(isEdit) {
|
||||
const companyStore = useCompanyStore()
|
||||
const customerStore = useCustomerStore()
|
||||
const itemStore = useItemStore()
|
||||
const invoiceStore = useInvoiceStore()
|
||||
const taxTypeStore = useTaxTypeStore()
|
||||
const route = useRoute()
|
||||
|
||||
this.isFetchingInitialSettings = true
|
||||
this.newRecurringInvoice.currency = companyStore.selectedCompanyCurrency
|
||||
|
||||
if (route.query.customer) {
|
||||
let response = await customerStore.fetchCustomer(route.query.customer)
|
||||
this.newRecurringInvoice.customer = response.data.data
|
||||
this.selectCustomer(response.data.data.id)
|
||||
}
|
||||
|
||||
let editActions = []
|
||||
|
||||
// on create
|
||||
if (!isEdit) {
|
||||
this.newRecurringInvoice.tax_per_item =
|
||||
companyStore.selectedCompanySettings.tax_per_item
|
||||
this.newRecurringInvoice.discount_per_item =
|
||||
companyStore.selectedCompanySettings.discount_per_item
|
||||
this.newRecurringInvoice.starts_at = moment().format('YYYY-MM-DD')
|
||||
this.newRecurringInvoice.next_invoice_date = moment()
|
||||
.add(7, 'days')
|
||||
.format('YYYY-MM-DD')
|
||||
} else {
|
||||
editActions = [this.fetchRecurringInvoice(route.params.id)]
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
itemStore.fetchItems({
|
||||
filter: {},
|
||||
orderByField: '',
|
||||
orderBy: '',
|
||||
}),
|
||||
this.resetSelectedNote(),
|
||||
invoiceStore.fetchInvoiceTemplates(),
|
||||
taxTypeStore.fetchTaxTypes({ limit: 'all' }),
|
||||
...editActions,
|
||||
])
|
||||
.then(async ([res1, res2, res3, res4, res5]) => {
|
||||
if (res3.data) {
|
||||
this.templates = invoiceStore.templates
|
||||
}
|
||||
|
||||
if (!isEdit) {
|
||||
this.setTemplate(this.templates[0].name)
|
||||
}
|
||||
|
||||
if (isEdit && res5?.data) {
|
||||
let data = {
|
||||
...res5.data.data,
|
||||
}
|
||||
|
||||
this.setTemplate(res5?.data?.data?.template_name)
|
||||
}
|
||||
|
||||
this.isFetchingInitialSettings = false
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
})
|
||||
},
|
||||
|
||||
setTemplate(data) {
|
||||
this.newRecurringInvoice.template_name = data
|
||||
},
|
||||
|
||||
setSelectedFrequency() {
|
||||
this.newRecurringInvoice.selectedFrequency = this.frequencies.find(
|
||||
(frequency) => {
|
||||
return frequency.value === this.newRecurringInvoice.frequency
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
resetSelectedNote() {
|
||||
this.newRecurringInvoice.selectedNote = null
|
||||
},
|
||||
|
||||
fetchRecurringInvoiceFrequencyDate(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/recurring-invoice-frequency', { params })
|
||||
.then((response) => {
|
||||
this.newRecurringInvoice.next_invoice_at =
|
||||
response.data.next_invoice_at
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'error',
|
||||
message: global.t('errors.enter_valid_cron_format'),
|
||||
})
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
91
resources/scripts/stores/reset.js
Normal file
91
resources/scripts/stores/reset.js
Normal file
@ -0,0 +1,91 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useBackupStore } from './backup'
|
||||
import { useCategoryStore } from './category'
|
||||
import { useCompanyStore } from './company'
|
||||
import { useCustomFieldStore } from './custom-field'
|
||||
import { useCustomerStore } from './customer'
|
||||
import { useDashboardStore } from './dashboard'
|
||||
import { useDialogStore } from './dialog'
|
||||
import { useDiskStore } from './disk'
|
||||
import { useEstimateStore } from './estimate'
|
||||
import { useExchangeRateStore } from './exchange-rate'
|
||||
import { useExpenseStore } from './expense'
|
||||
import { useGlobalStore } from './global'
|
||||
import { useInstallationStore } from './installation'
|
||||
import { useInvoiceStore } from './invoice'
|
||||
import { useItemStore } from './item'
|
||||
import { useMailDriverStore } from './mail-driver'
|
||||
import { useModalStore } from './modal'
|
||||
import { useNotesStore } from './note'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { usePaymentStore } from './payment'
|
||||
import { useRecurringInvoiceStore } from './recurring-invoice'
|
||||
import { useRoleStore } from './role'
|
||||
import { useTaxTypeStore } from './tax-type'
|
||||
import { useUserStore } from './user'
|
||||
import { useUsersStore } from './users'
|
||||
|
||||
export const useResetStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'reset',
|
||||
actions: {
|
||||
clearPinia() {
|
||||
const backupStore = useBackupStore()
|
||||
const categoryStore = useCategoryStore()
|
||||
const companyStore = useCompanyStore()
|
||||
const customFieldStore = useCustomFieldStore()
|
||||
const customerStore = useCustomerStore()
|
||||
const dashboardStore = useDashboardStore()
|
||||
const dialogStore = useDialogStore()
|
||||
const diskStore = useDiskStore()
|
||||
const estimateStore = useEstimateStore()
|
||||
const exchangeRateStore = useExchangeRateStore()
|
||||
const expenseStore = useExpenseStore()
|
||||
const globalStore = useGlobalStore()
|
||||
const installationStore = useInstallationStore()
|
||||
const invoiceStore = useInvoiceStore()
|
||||
const itemStore = useItemStore()
|
||||
const mailDriverStore = useMailDriverStore()
|
||||
const modalStore = useModalStore()
|
||||
const noteStore = useNotesStore()
|
||||
const notificationStore = useNotificationStore()
|
||||
const paymentStore = usePaymentStore()
|
||||
const recurringInvoiceStore = useRecurringInvoiceStore()
|
||||
const roleStore = useRoleStore()
|
||||
const taxTypeStore = useTaxTypeStore()
|
||||
const userStore = useUserStore()
|
||||
const usersStore = useUsersStore()
|
||||
|
||||
backupStore.$reset()
|
||||
categoryStore.$reset()
|
||||
companyStore.$reset()
|
||||
customFieldStore.$reset()
|
||||
customerStore.$reset()
|
||||
dashboardStore.$reset()
|
||||
dialogStore.$reset()
|
||||
diskStore.$reset()
|
||||
estimateStore.$reset()
|
||||
exchangeRateStore.$reset()
|
||||
expenseStore.$reset()
|
||||
globalStore.$reset()
|
||||
installationStore.$reset()
|
||||
invoiceStore.$reset()
|
||||
itemStore.$reset()
|
||||
mailDriverStore.$reset()
|
||||
modalStore.$reset()
|
||||
noteStore.$reset()
|
||||
notificationStore.$reset()
|
||||
paymentStore.$reset()
|
||||
recurringInvoiceStore.$reset()
|
||||
roleStore.$reset()
|
||||
taxTypeStore.$reset()
|
||||
userStore.$reset()
|
||||
usersStore.$reset()
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
169
resources/scripts/stores/role.js
Normal file
169
resources/scripts/stores/role.js
Normal file
@ -0,0 +1,169 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import _ from 'lodash'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useRoleStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'role',
|
||||
state: () => ({
|
||||
roles: [],
|
||||
allAbilities: [],
|
||||
selectedRoles: [],
|
||||
currentRole: {
|
||||
id: null,
|
||||
name: '',
|
||||
abilities: [],
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
isEdit: (state) => (state.currentRole.id ? true : false),
|
||||
abilitiesList: (state) => {
|
||||
let abilities = state.allAbilities.map((a) => ({
|
||||
modelName: a.model
|
||||
? a.model.substring(a.model.lastIndexOf('\\') + 1)
|
||||
: 'Common',
|
||||
disabled: false,
|
||||
...a,
|
||||
}))
|
||||
return _.groupBy(abilities, 'modelName')
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
fetchRoles(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/roles`, { params })
|
||||
.then((response) => {
|
||||
this.roles = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchRole(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/roles/${id}`)
|
||||
.then((response) => {
|
||||
this.currentRole.name = response.data.data.name
|
||||
this.currentRole.id = response.data.data.id
|
||||
|
||||
response.data.data.abilities.forEach((_ra) => {
|
||||
for (const property in this.abilitiesList) {
|
||||
this.abilitiesList[property].forEach((_p) => {
|
||||
if (_p.ability === _ra.name) {
|
||||
this.currentRole.abilities.push(_p)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addRole(data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/roles', data)
|
||||
.then((response) => {
|
||||
this.roles.push(response.data.role)
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.roles.created_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateRole(data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/roles/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
let pos = this.roles.findIndex(
|
||||
(role) => role.id === response.data.data.id
|
||||
)
|
||||
this.roles[pos] = data.role
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.roles.updated_message'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchAbilities(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.allAbilities.length) {
|
||||
resolve(this.allAbilities)
|
||||
} else {
|
||||
axios
|
||||
.get(`/api/v1/abilities`, { params })
|
||||
.then((response) => {
|
||||
this.allAbilities = response.data.abilities
|
||||
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
deleteRole(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.delete(`/api/v1/roles/${id}`)
|
||||
.then((response) => {
|
||||
let index = this.roles.findIndex((role) => role.id === id)
|
||||
this.roles.splice(index, 1)
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.roles.deleted_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
142
resources/scripts/stores/tax-type.js
Normal file
142
resources/scripts/stores/tax-type.js
Normal file
@ -0,0 +1,142 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useTaxTypeStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'taxType',
|
||||
|
||||
state: () => ({
|
||||
taxTypes: [],
|
||||
currentTaxType: {
|
||||
id: null,
|
||||
name: '',
|
||||
percent: 0,
|
||||
description: '',
|
||||
compound_tax: false,
|
||||
collective_tax: 0,
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
isEdit: (state) => (state.currentTaxType.id ? true : false),
|
||||
},
|
||||
|
||||
actions: {
|
||||
resetCurrentTaxType() {
|
||||
this.currentTaxType = {
|
||||
id: null,
|
||||
name: '',
|
||||
percent: 0,
|
||||
description: '',
|
||||
compound_tax: false,
|
||||
collective_tax: 0,
|
||||
}
|
||||
},
|
||||
|
||||
fetchTaxTypes(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/tax-types`, { params })
|
||||
.then((response) => {
|
||||
this.taxTypes = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchTaxType(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios
|
||||
.get(`/api/v1/tax-types/${id}`)
|
||||
.then((response) => {
|
||||
this.currentTaxType = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addTaxType(data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/tax-types', data)
|
||||
.then((response) => {
|
||||
this.taxTypes.push(response.data.data)
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.tax_types.created_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateTaxType(data) {
|
||||
const notificationStore = useNotificationStore()
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/tax-types/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response.data) {
|
||||
let pos = this.taxTypes.findIndex(
|
||||
(taxTypes) => taxTypes.id === response.data.data.id
|
||||
)
|
||||
this.taxTypes[pos] = data.taxTypes
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.tax_types.updated_message'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteTaxType(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios
|
||||
.delete(`/api/v1/tax-types/${id}`)
|
||||
.then((response) => {
|
||||
if (response.data.success) {
|
||||
let index = this.taxTypes.findIndex(
|
||||
(taxType) => taxType.id === id
|
||||
)
|
||||
this.taxTypes.splice(index, 1)
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.tax_types.deleted_message'),
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
147
resources/scripts/stores/user.js
Normal file
147
resources/scripts/stores/user.js
Normal file
@ -0,0 +1,147 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { handleError } from '@/scripts/helpers/error-handling'
|
||||
|
||||
export const useUserStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'user',
|
||||
|
||||
state: () => ({
|
||||
currentUser: null,
|
||||
currentAbilities: [],
|
||||
currentUserSettings: {},
|
||||
|
||||
userForm: {
|
||||
name: '',
|
||||
email: '',
|
||||
password: '',
|
||||
confirm_password: '',
|
||||
language: '',
|
||||
},
|
||||
}),
|
||||
|
||||
getters: {
|
||||
currentAbilitiesCount: (state) => state.currentAbilities.length,
|
||||
},
|
||||
|
||||
actions: {
|
||||
updateCurrentUser(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put('/api/v1/me', data)
|
||||
.then((response) => {
|
||||
this.currentUser = response.data.data
|
||||
Object.assign(this.userForm, response.data.data)
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('settings.account_settings.updated_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchCurrentUser(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/me`, params)
|
||||
.then((response) => {
|
||||
this.currentUser = response.data.data
|
||||
this.userForm = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
uploadAvatar(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/me/upload-avatar', data)
|
||||
.then((response) => {
|
||||
this.currentUser.avatar = response.data.data.avatar
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchUserSettings(settings) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/v1/me/settings', {
|
||||
params: {
|
||||
settings,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateUserSettings(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put('/api/v1/me/settings', data)
|
||||
.then((response) => {
|
||||
if (data.settings.language) {
|
||||
this.currentUserSettings.language = data.settings.language
|
||||
global.locale = data.settings.language
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
hasAbilities(abilities) {
|
||||
return !!this.currentAbilities.find((ab) => {
|
||||
if (ab.name === '*') return true
|
||||
if (typeof abilities === 'string') {
|
||||
return ab.name === abilities
|
||||
}
|
||||
return !!abilities.find((p) => {
|
||||
return ab.name === p
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
hasAllAbilities(abilities) {
|
||||
let isAvailable = true
|
||||
this.currentAbilities.filter((ab) => {
|
||||
let hasContain = !!abilities.find((p) => {
|
||||
return ab.name === p
|
||||
})
|
||||
if (!hasContain) {
|
||||
isAvailable = false
|
||||
}
|
||||
})
|
||||
|
||||
return isAvailable
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
232
resources/scripts/stores/users.js
Normal file
232
resources/scripts/stores/users.js
Normal file
@ -0,0 +1,232 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useNotificationStore } from './notification'
|
||||
import { handleError } from '../helpers/error-handling'
|
||||
|
||||
export const useUsersStore = (useWindow = false) => {
|
||||
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
|
||||
const { global } = window.i18n
|
||||
|
||||
return defineStoreFunc({
|
||||
id: 'users',
|
||||
state: () => ({
|
||||
roles: [],
|
||||
users: [],
|
||||
totalUsers: 0,
|
||||
currentUser: null,
|
||||
selectAllField: false,
|
||||
selectedUsers: [],
|
||||
customerList: [],
|
||||
userList: [],
|
||||
|
||||
userData: {
|
||||
name: '',
|
||||
email: '',
|
||||
password: null,
|
||||
phone: null,
|
||||
companies: [],
|
||||
},
|
||||
}),
|
||||
|
||||
actions: {
|
||||
resetUserData() {
|
||||
this.userData = {
|
||||
name: '',
|
||||
email: '',
|
||||
password: null,
|
||||
phone: null,
|
||||
role: null,
|
||||
companies: [],
|
||||
}
|
||||
},
|
||||
|
||||
fetchUsers(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/users`, { params })
|
||||
.then((response) => {
|
||||
this.users = response.data.data
|
||||
this.totalUsers = response.data.meta.total
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchUser(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/users/${id}`)
|
||||
.then((response) => {
|
||||
this.userData = response.data.data
|
||||
if (this.userData?.companies?.length) {
|
||||
this.userData.companies.forEach((c, i) => {
|
||||
this.userData.roles.forEach((r) => {
|
||||
if (r.scope === c.id)
|
||||
this.userData.companies[i].role = r.name
|
||||
})
|
||||
})
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
fetchRoles(state) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(`/api/v1/roles`)
|
||||
.then((response) => {
|
||||
this.roles = response.data.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
addUser(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post('/api/v1/users', data)
|
||||
.then((response) => {
|
||||
this.users.push(response.data)
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('users.created_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
updateUser(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.put(`/api/v1/users/${data.id}`, data)
|
||||
.then((response) => {
|
||||
if (response) {
|
||||
let pos = this.users.findIndex(
|
||||
(user) => user.id === response.data.data.id
|
||||
)
|
||||
this.users[pos] = response.data.data
|
||||
}
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.t('users.updated_message'),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteUser(id) {
|
||||
const notificationStore = useNotificationStore()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/users/delete`, { users: id.ids })
|
||||
.then((response) => {
|
||||
let index = this.users.findIndex((user) => user.id === id)
|
||||
this.users.splice(index, 1)
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('users.deleted_message', 1),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
deleteMultipleUsers() {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.post(`/api/v1/users/delete`, { users: this.selectedUsers })
|
||||
.then((response) => {
|
||||
this.selectedUsers.forEach((user) => {
|
||||
let index = this.users.findIndex(
|
||||
(_user) => _user.id === user.id
|
||||
)
|
||||
this.users.splice(index, 1)
|
||||
})
|
||||
const notificationStore = useNotificationStore()
|
||||
notificationStore.showNotification({
|
||||
type: 'success',
|
||||
message: global.tc('users.deleted_message', 2),
|
||||
})
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
searchUsers(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios
|
||||
.get(`/api/v1/search`, { params })
|
||||
.then((response) => {
|
||||
this.userList = response.data.users.data
|
||||
this.customerList = response.data.customers.data
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
setSelectAllState(data) {
|
||||
this.selectAllField = data
|
||||
},
|
||||
|
||||
selectUser(data) {
|
||||
this.selectedUsers = data
|
||||
if (this.selectedUsers.length === this.users.length) {
|
||||
this.selectAllField = true
|
||||
} else {
|
||||
this.selectAllField = false
|
||||
}
|
||||
},
|
||||
|
||||
selectAllUsers() {
|
||||
if (this.selectedUsers.length === this.users.length) {
|
||||
this.selectedUsers = []
|
||||
this.selectAllField = false
|
||||
} else {
|
||||
let allUserIds = this.users.map((user) => user.id)
|
||||
this.selectedUsers = allUserIds
|
||||
this.selectAllField = true
|
||||
}
|
||||
},
|
||||
},
|
||||
})()
|
||||
}
|
||||
Reference in New Issue
Block a user