v5.0.0 update

This commit is contained in:
Mohit Panjwani
2021-11-30 18:58:19 +05:30
parent d332712c22
commit 082d5cacf2
1253 changed files with 88309 additions and 71741 deletions

View 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)
})
})
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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 }
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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)
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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
})
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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)
})
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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)
}
}
})()
}

View 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)
})
})
},
},
})()
}

View 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
})
}
}
})()
}

View 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)
})
})
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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()
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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)
})
})
},
},
})()
}

View 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
},
},
})()
}

View 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
}
},
},
})()
}