mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-28 12:11:08 -04:00
Fix Invoice/Estimate template issues and Add Payment Receipt, Custom Payment Modes and Item units
This commit is contained in:
committed by
Mohit Panjwani
parent
56a955befd
commit
4c33a5d88c
2
resources/assets/js/bootstrap.js
vendored
2
resources/assets/js/bootstrap.js
vendored
@ -12,6 +12,7 @@ import CustomerModal from './components/base/modal/CustomerModal.vue'
|
||||
import TaxTypeModal from './components/base/modal/TaxTypeModal.vue'
|
||||
import CategoryModal from './components/base/modal/CategoryModal.vue'
|
||||
import money from 'v-money'
|
||||
import VTooltip from 'v-tooltip'
|
||||
|
||||
/**
|
||||
* Global css plugins
|
||||
@ -107,6 +108,7 @@ window.toastr = require('toastr')
|
||||
|
||||
Vue.use(VueRouter)
|
||||
Vue.use(Vuex)
|
||||
Vue.use(VTooltip)
|
||||
|
||||
// register directive v-money and component <money>
|
||||
Vue.use(money, {precision: 2})
|
||||
|
||||
@ -21,6 +21,9 @@ import EstimateTemplate from './EstimateTemplate'
|
||||
import InvoiceTemplate from './InvoiceTemplate'
|
||||
import CustomerModal from './CustomerModal'
|
||||
import CategoryModal from './CategoryModal'
|
||||
import PaymentMode from './PaymentModeModal'
|
||||
import ItemUnit from './ItemUnitModal'
|
||||
import MailTestModal from './MailTestModal'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -29,7 +32,10 @@ export default {
|
||||
EstimateTemplate,
|
||||
InvoiceTemplate,
|
||||
CustomerModal,
|
||||
CategoryModal
|
||||
CategoryModal,
|
||||
PaymentMode,
|
||||
ItemUnit,
|
||||
MailTestModal
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
@ -341,6 +341,7 @@ export default {
|
||||
mixins: [validationMixin],
|
||||
data () {
|
||||
return {
|
||||
isEdit: false,
|
||||
isLoading: false,
|
||||
countryList: [],
|
||||
billingCountry: null,
|
||||
@ -399,9 +400,22 @@ export default {
|
||||
...mapGetters('currency', [
|
||||
'defaultCurrency',
|
||||
'currencies'
|
||||
]),
|
||||
...mapGetters('modal', [
|
||||
'modalDataID',
|
||||
'modalData',
|
||||
'modalActive'
|
||||
])
|
||||
},
|
||||
watch: {
|
||||
'modalDataID' (val) {
|
||||
if (val) {
|
||||
this.isEdit = true
|
||||
this.setData()
|
||||
} else {
|
||||
this.isEdit = false
|
||||
}
|
||||
},
|
||||
billingCountry () {
|
||||
if (this.billingCountry) {
|
||||
this.billing.country_id = this.billingCountry.id
|
||||
@ -419,6 +433,9 @@ export default {
|
||||
this.$refs.name.focus = true
|
||||
this.currency = this.defaultCurrency
|
||||
this.fetchCountry()
|
||||
if (this.modalDataID) {
|
||||
this.setData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('invoice', {
|
||||
@ -493,6 +510,24 @@ export default {
|
||||
this.formData.addresses = [{...this.shipping, type: 'shipping'}]
|
||||
return true
|
||||
},
|
||||
async setData () {
|
||||
this.formData.id = this.modalData.id
|
||||
this.formData.name = this.modalData.name
|
||||
this.formData.email = this.modalData.email
|
||||
this.formData.contact_name = this.modalData.contact_name
|
||||
this.formData.phone = this.modalData.phone
|
||||
this.formData.website = this.modalData.website
|
||||
this.currency = this.modalData.currency
|
||||
|
||||
if (this.modalData.billing_address) {
|
||||
this.billing = this.modalData.billing_address
|
||||
this.billingCountry = this.modalData.billing_address.country
|
||||
}
|
||||
if (this.modalData.shipping_address) {
|
||||
this.shipping = this.modalData.shipping_address
|
||||
this.shippingCountry = this.modalData.shipping_address.country
|
||||
}
|
||||
},
|
||||
async submitCustomerData () {
|
||||
this.$v.formData.$touch()
|
||||
|
||||
@ -510,14 +545,23 @@ export default {
|
||||
this.formData.currency_id = this.defaultCurrency.id
|
||||
}
|
||||
try {
|
||||
let response = await this.addCustomer(this.formData)
|
||||
let response = null
|
||||
if (this.modalDataID) {
|
||||
response = await this.updateCustomer(this.formData)
|
||||
} else {
|
||||
response = await this.addCustomer(this.formData)
|
||||
}
|
||||
if (response.data) {
|
||||
window.toastr['success'](this.$tc('customers.created_message'))
|
||||
if (this.modalDataID) {
|
||||
window.toastr['success'](this.$tc('customers.updated_message'))
|
||||
} else {
|
||||
window.toastr['success'](this.$tc('customers.created_message'))
|
||||
}
|
||||
this.isLoading = false
|
||||
if (this.$route.name === 'invoices.create') {
|
||||
if (this.$route.name === 'invoices.create' || this.$route.name === 'invoices.edit') {
|
||||
this.setInvoiceCustomer(response.data.customer.id)
|
||||
}
|
||||
if (this.$route.name === 'estimates.create') {
|
||||
if (this.$route.name === 'estimates.create' || this.$route.name === 'estimates.edit') {
|
||||
this.setEstimateCustomer(response.data.customer.id)
|
||||
}
|
||||
this.resetData()
|
||||
|
||||
@ -45,14 +45,34 @@
|
||||
<div class="col-sm-7">
|
||||
<base-select
|
||||
v-model="formData.unit"
|
||||
:options="units"
|
||||
:options="itemUnits"
|
||||
:searchable="true"
|
||||
:show-labels="false"
|
||||
label="name"
|
||||
>
|
||||
<div slot="afterList">
|
||||
<button type="button" class="list-add-button" @click="addItemUnit">
|
||||
<font-awesome-icon class="icon" icon="cart-plus" />
|
||||
<label>{{ $t('settings.customization.items.add_item_unit') }}</label>
|
||||
</button>
|
||||
</div>
|
||||
</base-select>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isTexPerItem" class="form-group row">
|
||||
<label class="col-sm-4 col-form-label input-label">{{ $t('items.taxes') }}</label>
|
||||
<div class="col-sm-7">
|
||||
<base-select
|
||||
v-model="formData.taxes"
|
||||
:options="getTaxTypes"
|
||||
:searchable="true"
|
||||
:show-labels="false"
|
||||
:allow-empty="true"
|
||||
:multiple="true"
|
||||
label="tax_name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label input-label">{{ $t('items.description') }}</label>
|
||||
<div class="col-sm-7">
|
||||
@ -124,11 +144,13 @@ export default {
|
||||
{ name: 'mg', value: 'mg' },
|
||||
{ name: 'pc', value: 'pc' }
|
||||
],
|
||||
taxes: [],
|
||||
formData: {
|
||||
name: null,
|
||||
price: null,
|
||||
description: null,
|
||||
unit: null
|
||||
unit: null,
|
||||
taxes: []
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -161,12 +183,28 @@ export default {
|
||||
this.formData.price = newValue * 100
|
||||
}
|
||||
},
|
||||
// itemUnits () {
|
||||
// return this.units
|
||||
// },
|
||||
...mapGetters('modal', [
|
||||
'modalDataID'
|
||||
'modalDataID',
|
||||
'modalData'
|
||||
]),
|
||||
...mapGetters('item', [
|
||||
'getItemById'
|
||||
])
|
||||
'getItemById',
|
||||
'itemUnits'
|
||||
]),
|
||||
...mapGetters('taxType', [
|
||||
'taxTypes'
|
||||
]),
|
||||
isTexPerItem () {
|
||||
return this.modalData.taxPerItem === 'YES'
|
||||
},
|
||||
getTaxTypes () {
|
||||
return this.taxTypes.map(tax => {
|
||||
return {...tax, tax_name: tax.name + ' (' + tax.percent + '%)'}
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
modalDataID () {
|
||||
@ -179,12 +217,17 @@ export default {
|
||||
this.isEdit = true
|
||||
this.fetchEditData()
|
||||
}
|
||||
|
||||
if (this.isEdit) {
|
||||
this.loadEditData()
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$refs.name.focus = true
|
||||
},
|
||||
methods: {
|
||||
...mapActions('modal', [
|
||||
'openModal',
|
||||
'closeModal',
|
||||
'resetModalData'
|
||||
]),
|
||||
@ -203,7 +246,6 @@ export default {
|
||||
unit: null,
|
||||
id: null
|
||||
}
|
||||
|
||||
this.$v.$reset()
|
||||
},
|
||||
fetchEditData () {
|
||||
@ -230,9 +272,20 @@ export default {
|
||||
if (this.isEdit) {
|
||||
response = await this.updateItem(this.formData)
|
||||
} else {
|
||||
response = await this.addItem(this.formData)
|
||||
let data = {
|
||||
...this.formData,
|
||||
taxes: this.formData.taxes.map(tax => {
|
||||
return {
|
||||
tax_type_id: tax.id,
|
||||
amount: ((this.formData.price * tax.percent) / 100),
|
||||
percent: tax.percent,
|
||||
name: tax.name,
|
||||
collective_tax: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
response = await this.addItem(data)
|
||||
}
|
||||
|
||||
if (response.data) {
|
||||
window.toastr['success'](this.$tc('items.created_message'))
|
||||
this.setItem(response.data.item)
|
||||
@ -245,6 +298,12 @@ export default {
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
},
|
||||
async addItemUnit () {
|
||||
this.openModal({
|
||||
'title': 'Add Item Unit',
|
||||
'componentName': 'ItemUnit'
|
||||
})
|
||||
},
|
||||
closeItemModal () {
|
||||
this.resetFormData()
|
||||
this.closeModal()
|
||||
|
||||
148
resources/assets/js/components/base/modal/ItemUnitModal.vue
Normal file
148
resources/assets/js/components/base/modal/ItemUnitModal.vue
Normal file
@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<div class="item-unit-modal">
|
||||
<form action="" @submit.prevent="submitItemUnit">
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label input-label">{{ $t('settings.customization.items.unit_name') }} <span class="required"> *</span></label>
|
||||
<div class="col-sm-7">
|
||||
<base-input
|
||||
ref="name"
|
||||
:invalid="$v.formData.name.$error"
|
||||
v-model="formData.name"
|
||||
type="text"
|
||||
@input="$v.formData.name.$touch()"
|
||||
/>
|
||||
<div v-if="$v.formData.name.$error">
|
||||
<span v-if="!$v.formData.name.required" class="form-group__message text-danger">{{ $tc('validation.required') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<base-button
|
||||
:outline="true"
|
||||
class="mr-3"
|
||||
color="theme"
|
||||
type="button"
|
||||
@click="closePaymentModeModal"
|
||||
>
|
||||
{{ $t('general.cancel') }}
|
||||
</base-button>
|
||||
<base-button
|
||||
:loading="isLoading"
|
||||
color="theme"
|
||||
icon="save"
|
||||
type="submit"
|
||||
>
|
||||
{{ !isEdit ? $t('general.save') : $t('general.update') }}
|
||||
</base-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import { validationMixin } from 'vuelidate'
|
||||
const { required, minLength } = require('vuelidate/lib/validators')
|
||||
export default {
|
||||
mixins: [validationMixin],
|
||||
data () {
|
||||
return {
|
||||
isEdit: false,
|
||||
isLoading: false,
|
||||
formData: {
|
||||
id: null,
|
||||
name: null
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('modal', [
|
||||
'modalDataID',
|
||||
'modalData',
|
||||
'modalActive'
|
||||
])
|
||||
},
|
||||
validations: {
|
||||
formData: {
|
||||
name: {
|
||||
required,
|
||||
minLength: minLength(2)
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted () {
|
||||
this.$refs.name.focus = true
|
||||
if (this.modalDataID) {
|
||||
this.isEdit = true
|
||||
this.setData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('modal', [
|
||||
'closeModal',
|
||||
'resetModalData'
|
||||
]),
|
||||
...mapActions('item', [
|
||||
'addItemUnit',
|
||||
'updateItemUnit',
|
||||
'fatchItemUnit'
|
||||
]),
|
||||
resetFormData () {
|
||||
this.formData = {
|
||||
id: null,
|
||||
name: null
|
||||
}
|
||||
this.$v.formData.$reset()
|
||||
},
|
||||
async submitItemUnit () {
|
||||
this.$v.formData.$touch()
|
||||
if (this.$v.$invalid) {
|
||||
return true
|
||||
}
|
||||
this.isLoading = true
|
||||
|
||||
let response
|
||||
|
||||
if (this.isEdit) {
|
||||
response = await this.updateItemUnit(this.formData)
|
||||
|
||||
if (response.data) {
|
||||
window.toastr['success'](this.$t('settings.customization.items.item_unit_updated'))
|
||||
this.closePaymentModeModal()
|
||||
return true
|
||||
}
|
||||
|
||||
window.toastr['error'](response.data.error)
|
||||
} else {
|
||||
try {
|
||||
response = await this.addItemUnit(this.formData)
|
||||
if (response.data) {
|
||||
this.isLoading = false
|
||||
window.toastr['success'](this.$t('settings.customization.items.item_unit_added'))
|
||||
this.closePaymentModeModal()
|
||||
return true
|
||||
} window.toastr['error'](response.data.error)
|
||||
} catch (err) {
|
||||
if (err.response.data.errors.name) {
|
||||
this.isLoading = true
|
||||
window.toastr['error'](this.$t('validation.item_unit_already_taken'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
async setData () {
|
||||
this.formData = {
|
||||
id: this.modalData.id,
|
||||
name: this.modalData.name
|
||||
}
|
||||
},
|
||||
closePaymentModeModal () {
|
||||
this.resetModalData()
|
||||
this.resetFormData()
|
||||
this.closeModal()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
166
resources/assets/js/components/base/modal/MailTestModal.vue
Normal file
166
resources/assets/js/components/base/modal/MailTestModal.vue
Normal file
@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<div class="mail-test-modal">
|
||||
<form action="" @submit.prevent="onTestMailSend">
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label input-label">{{ $t('general.to') }} <span class="required"> *</span></label>
|
||||
<div class="col-sm-7">
|
||||
<base-input
|
||||
ref="to"
|
||||
:invalid="$v.formData.to.$error"
|
||||
v-model="formData.to"
|
||||
type="text"
|
||||
@input="$v.formData.to.$touch()"
|
||||
/>
|
||||
<div v-if="$v.formData.to.$error">
|
||||
<span v-if="!$v.formData.to.required" class="form-group__message text-danger">{{ $tc('validation.required') }}</span>
|
||||
<span v-if="!$v.formData.to.email" class="form-group__message text-danger"> {{ $t('validation.email_incorrect') }} </span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label input-label">{{ $t('general.subject') }} <span class="required"> *</span></label>
|
||||
<div class="col-sm-7">
|
||||
<div class="base-input">
|
||||
<base-input
|
||||
:invalid="$v.formData.subject.$error"
|
||||
v-model="formData.subject"
|
||||
type="text"
|
||||
@input="$v.formData.subject.$touch()"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="$v.formData.subject.$error">
|
||||
<span v-if="!$v.formData.subject.required" class="text-danger">{{ $t('validation.required') }}</span>
|
||||
<span v-if="!$v.formData.subject.maxLength" class="text-danger">{{ $t('validation.subject_maxlength') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label input-label">{{ $t('general.message') }}<span class="required"> *</span></label>
|
||||
<div class="col-sm-7">
|
||||
<base-text-area
|
||||
v-model="formData.message"
|
||||
:invalid="$v.formData.message.$error"
|
||||
rows="4"
|
||||
cols="50"
|
||||
@input="$v.formData.message.$touch()"
|
||||
/>
|
||||
<div v-if="$v.formData.message.$error">
|
||||
<span v-if="!$v.formData.message.required" class="text-danger">{{ $t('validation.required') }}</span>
|
||||
<span v-if="!$v.formData.message.maxLength" class="text-danger">{{ $t('validation.message_maxlength') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<base-button
|
||||
:outline="true"
|
||||
class="mr-3"
|
||||
color="theme"
|
||||
type="button"
|
||||
@click="closeTaxModal"
|
||||
>
|
||||
{{ $t('general.cancel') }}
|
||||
</base-button>
|
||||
<base-button
|
||||
:loading="isLoading"
|
||||
color="theme"
|
||||
icon="save"
|
||||
type="submit"
|
||||
>
|
||||
{{ !isEdit ? $t('general.save') : $t('general.update') }}
|
||||
</base-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import { validationMixin } from 'vuelidate'
|
||||
const { required, minLength, email, maxLength } = require('vuelidate/lib/validators')
|
||||
export default {
|
||||
mixins: [validationMixin],
|
||||
data () {
|
||||
return {
|
||||
isEdit: false,
|
||||
isLoading: false,
|
||||
formData: {
|
||||
to: null,
|
||||
subject: null,
|
||||
message: null
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('modal', [
|
||||
'modalDataID',
|
||||
'modalData',
|
||||
'modalActive'
|
||||
])
|
||||
},
|
||||
validations: {
|
||||
formData: {
|
||||
to: {
|
||||
required,
|
||||
email
|
||||
},
|
||||
subject: {
|
||||
required,
|
||||
maxLength: maxLength(100)
|
||||
},
|
||||
message: {
|
||||
required,
|
||||
maxLength: maxLength(255)
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted () {
|
||||
this.$refs.to.focus = true
|
||||
},
|
||||
methods: {
|
||||
...mapActions('modal', [
|
||||
'closeModal',
|
||||
'resetModalData'
|
||||
]),
|
||||
resetFormData () {
|
||||
this.formData = {
|
||||
to: null,
|
||||
subject: null,
|
||||
message: null
|
||||
}
|
||||
this.$v.formData.$reset()
|
||||
},
|
||||
async onTestMailSend () {
|
||||
this.$v.formData.$touch()
|
||||
|
||||
if (this.$v.$invalid) {
|
||||
return true
|
||||
}
|
||||
|
||||
this.isLoading = true
|
||||
let response = await axios.post('/api/settings/test/mail', this.formData)
|
||||
if (response.data) {
|
||||
|
||||
if (response.data.success) {
|
||||
window.toastr['success'](this.$tc('general.send_mail_successfully'))
|
||||
this.closeTaxModal()
|
||||
this.isLoading = false
|
||||
return true
|
||||
}
|
||||
|
||||
window.toastr['error'](this.$tc('validation.something_went_wrong'))
|
||||
this.closeTaxModal()
|
||||
this.isLoading = false
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
},
|
||||
closeTaxModal () {
|
||||
this.resetModalData()
|
||||
this.resetFormData()
|
||||
this.closeModal()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
143
resources/assets/js/components/base/modal/PaymentModeModal.vue
Normal file
143
resources/assets/js/components/base/modal/PaymentModeModal.vue
Normal file
@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<div class="payment-modes-modal">
|
||||
<form action="" @submit.prevent="submitPaymentMode">
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label input-label">{{ $t('settings.customization.payments.mode_name') }} <span class="required"> *</span></label>
|
||||
<div class="col-sm-7">
|
||||
<base-input
|
||||
ref="name"
|
||||
:invalid="$v.formData.name.$error"
|
||||
v-model="formData.name"
|
||||
type="text"
|
||||
@input="$v.formData.name.$touch()"
|
||||
/>
|
||||
<div v-if="$v.formData.name.$error">
|
||||
<span v-if="!$v.formData.name.required" class="form-group__message text-danger">{{ $tc('validation.required') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<base-button
|
||||
:outline="true"
|
||||
class="mr-3"
|
||||
color="theme"
|
||||
type="button"
|
||||
@click="closePaymentModeModal"
|
||||
>
|
||||
{{ $t('general.cancel') }}
|
||||
</base-button>
|
||||
<base-button
|
||||
:loading="isLoading"
|
||||
color="theme"
|
||||
icon="save"
|
||||
type="submit"
|
||||
>
|
||||
{{ !isEdit ? $t('general.save') : $t('general.update') }}
|
||||
</base-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import { validationMixin } from 'vuelidate'
|
||||
const { required, minLength } = require('vuelidate/lib/validators')
|
||||
|
||||
export default {
|
||||
mixins: [validationMixin],
|
||||
data () {
|
||||
return {
|
||||
isEdit: false,
|
||||
isLoading: false,
|
||||
formData: {
|
||||
id: null,
|
||||
name: null
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('modal', [
|
||||
'modalDataID',
|
||||
'modalData',
|
||||
'modalActive'
|
||||
])
|
||||
},
|
||||
validations: {
|
||||
formData: {
|
||||
name: {
|
||||
required,
|
||||
minLength: minLength(2)
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted () {
|
||||
this.$refs.name.focus = true
|
||||
if (this.modalDataID) {
|
||||
this.isEdit = true
|
||||
this.setData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('modal', [
|
||||
'closeModal',
|
||||
'resetModalData'
|
||||
]),
|
||||
...mapActions('payment', [
|
||||
'addPaymentMode',
|
||||
'updatePaymentMode'
|
||||
]),
|
||||
resetFormData () {
|
||||
this.formData = {
|
||||
id: null,
|
||||
name: null
|
||||
}
|
||||
this.$v.formData.$reset()
|
||||
},
|
||||
async submitPaymentMode () {
|
||||
this.$v.formData.$touch()
|
||||
if (this.$v.$invalid) {
|
||||
return true
|
||||
}
|
||||
this.isLoading = true
|
||||
let response
|
||||
if (this.isEdit) {
|
||||
response = await this.updatePaymentMode(this.formData)
|
||||
if (response.data) {
|
||||
window.toastr['success'](this.$t('settings.customization.payments.payment_mode_updated'))
|
||||
this.closePaymentModeModal()
|
||||
return true
|
||||
} window.toastr['error'](response.data.error)
|
||||
} else {
|
||||
try {
|
||||
response = await this.addPaymentMode(this.formData)
|
||||
if (response.data) {
|
||||
this.isLoading = false
|
||||
window.toastr['success'](this.$t('settings.customization.payments.payment_mode_added'))
|
||||
this.closePaymentModeModal()
|
||||
return true
|
||||
} window.toastr['error'](response.data.error)
|
||||
} catch (err) {
|
||||
if (err.response.data.errors.name) {
|
||||
this.isLoading = true
|
||||
window.toastr['error'](this.$t('validation.payment_mode_already_taken'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
async setData () {
|
||||
this.formData = {
|
||||
id: this.modalData.id,
|
||||
name: this.modalData.name
|
||||
}
|
||||
},
|
||||
closePaymentModeModal () {
|
||||
this.resetModalData()
|
||||
this.resetFormData()
|
||||
this.closeModal()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -852,6 +852,8 @@
|
||||
"email_incorrect": "بريد الكتروني غير صحيح.",
|
||||
"email_already_taken": "هذا البريد الالكتروني مستخدم مسبقاً",
|
||||
"email_does_not_exist": "لا يوجد كستخدم بهذا البريد الالكتروني",
|
||||
"item_unit_already_taken": "وحدة البند قد اتخذت بالفعل",
|
||||
"payment_mode_already_taken": "لقد تم بالفعل أخذ طريقة الدفع",
|
||||
"send_reset_link": "أرسال رابط استعادة كلمة المرور",
|
||||
"not_yet": "ليس بعد؟ أعد الإرسال الآن..",
|
||||
"password_min_length": "كلمة المرور يجب أن تتكون من {count} أحرف على الأقل",
|
||||
|
||||
877
resources/assets/js/plugins/de.json
Normal file
877
resources/assets/js/plugins/de.json
Normal file
@ -0,0 +1,877 @@
|
||||
{
|
||||
"credit_notes": {
|
||||
"action": "Aktion",
|
||||
"amount": "Summe",
|
||||
"confirm_delete": "Wollen Sie diese Gutschrift löschen?",
|
||||
"contact": "Kontakt",
|
||||
"credit_notes": "Gutschriften",
|
||||
"credit_notes_list": "Gutschriften-Liste",
|
||||
"credit_number": "Kreditkarten-Nummer",
|
||||
"date": "Datum",
|
||||
"item": {
|
||||
"description": "Beschreibung",
|
||||
"discount": "Rabatt",
|
||||
"price": "Preis",
|
||||
"quantity": "Menge",
|
||||
"sub_total": "Zwischensumme",
|
||||
"tax": "Steuer",
|
||||
"title": "Titel",
|
||||
"total": "Gesamt",
|
||||
"total_discount": "Rabatt Gesamt"
|
||||
},
|
||||
"notes": "Hinweise",
|
||||
"title": "Gutschriften"
|
||||
},
|
||||
"customers": {
|
||||
"action": "Aktion",
|
||||
"add_customer": "Kunde hinzufügen",
|
||||
"add_new_customer": "Neuen Kunden hinzufügen",
|
||||
"added_on": "Hinzugefügt am",
|
||||
"address": "Adresse",
|
||||
"amount_due": "Offener Betrag",
|
||||
"basic_info": "Basisinformation",
|
||||
"billing_address": "Rechnungsadresse",
|
||||
"city": "Stadt",
|
||||
"confirm_delete": "Sie können diesen Kunden nicht wiederherstellen | Sie können diese Kunden nicht wiederherstellen",
|
||||
"contact_name": "Kontakt Name",
|
||||
"contacts_list": "Kunden-Liste",
|
||||
"copy_billing_address": "Rechnungsadresse kopieren",
|
||||
"country": "Land",
|
||||
"created_message": "Kunde erfolgreich erstellt",
|
||||
"customer": "Kunde | Kunden",
|
||||
"deleted_message": "Kunden erfolgreich gelöscht | Kunden erfolgreich gelöscht",
|
||||
"display_name": "Anzeige Name",
|
||||
"edit_customer": "Kunde bearbeiten",
|
||||
"email": "E-Mail",
|
||||
"list_of_customers": "Dieser Abschnitt enthält die Liste der Kunden.",
|
||||
"name": "Name",
|
||||
"new_customer": "Neuer Kunde",
|
||||
"no_customers": "Noch keine Kunden!",
|
||||
"no_customers_found": "Keine Kunden gefunden!",
|
||||
"password": "Passwort",
|
||||
"phone": "Telefon",
|
||||
"primary_contact_name": "Ansprechpartner",
|
||||
"primary_currency": "Primäre Währung",
|
||||
"primary_display_name": "Primärer Anzeige Name",
|
||||
"save_customer": "Kunde speichern",
|
||||
"select_a_customer": "Wählen Sie einen Kunden",
|
||||
"select_city": "Stadt wählen",
|
||||
"select_country": "Land wählen",
|
||||
"select_currency": "Währung wählen",
|
||||
"select_state": "Bundesland wählen",
|
||||
"shipping_address": "Versand-Adresse",
|
||||
"state": "Bundesland",
|
||||
"street_1": "Strasse",
|
||||
"street_2": "Adresszusatz",
|
||||
"street_number": "Hausnummer",
|
||||
"title": "Kunden",
|
||||
"type_or_click": "Eingeben oder anklicken zum auswählen",
|
||||
"update_customer": "Kunden ändern",
|
||||
"updated_message": "Kunde erfolgreich aktualisiert",
|
||||
"website": "Webseite",
|
||||
"zip_code": "PLZ"
|
||||
},
|
||||
"dashboard": {
|
||||
"cards": {
|
||||
"customers": "Kunden",
|
||||
"due_amount": "Offene Beträge",
|
||||
"estimates": "Kostenvoranschläge",
|
||||
"invoices": "Rechnungen"
|
||||
},
|
||||
"chart_info": {
|
||||
"net_income": "Einnahmen Netto",
|
||||
"total_expense": "Gesamtausgaben",
|
||||
"total_receipts": "Eingänge gesamt",
|
||||
"total_sales": "Verkäufe gesamt",
|
||||
"year": "Jahr"
|
||||
},
|
||||
"monthly_chart": {
|
||||
"title": "Umsatz & Kosten"
|
||||
},
|
||||
"recent_estimate_card": {
|
||||
"actions": "Aktionen",
|
||||
"amount_due": "Betrag",
|
||||
"customer": "Kunden",
|
||||
"date": "Datum",
|
||||
"title": "Aktuelle Kostenvoranschläge",
|
||||
"view_all": "Alle Anzeigen"
|
||||
},
|
||||
"recent_invoices_card": {
|
||||
"actions": "Aktionen",
|
||||
"amount_due": "Offener Betrag",
|
||||
"customer": "Kunden",
|
||||
"due_on": "Fällig am",
|
||||
"title": "Fällige Rechnungen",
|
||||
"view_all": "Alle Anzeigen"
|
||||
},
|
||||
"select_year": "Jahr wählen",
|
||||
"weekly_invoices": {
|
||||
"title": "Wöchentliche Rechnungen"
|
||||
}
|
||||
},
|
||||
"estimates": {
|
||||
"Estimate": "Kostenvoranschlag | Kostenvoranschläge",
|
||||
"accepted": "Angenommen",
|
||||
"action": "Aktion",
|
||||
"add_estimate": "Kostenvoranschlag hinzufügen",
|
||||
"add_item": "Fügen Sie ein Artikel hinzu",
|
||||
"add_new_estimate": "Neuen Kostenvoranschlag hinzufügen",
|
||||
"add_new_tax": "neuen Steuersatz hinzufügen",
|
||||
"add_tax": "Steuer hinzufügen",
|
||||
"all": "Alle",
|
||||
"amount": "Summe",
|
||||
"amount_due": "OFFENER BETRAG",
|
||||
"confirm_conversion": "Sie möchten, konvertieren Sie diese Schätzung in die Rechnung?",
|
||||
"confirm_delete": "Der Kostenvoranschlag kann nicht wiederhergestellt werden | Die Kostenvoranschläge können nicht wiederhergestellt werden",
|
||||
"confirm_mark_as_accepted": "Dieser Kostenvoranschlag wird als angenommen markiert",
|
||||
"confirm_mark_as_rejected": "Dieser Kostenvoranschlag wird als abgelehnt markiert",
|
||||
"confirm_mark_as_sent": "Dieser Kostenvoranschlag wird als gesendet markiert",
|
||||
"confirm_send_estimate": "Der Kostenvoranschlag wird per E-Mail an den Kunden gesendet",
|
||||
"contact": "Kontakt",
|
||||
"conversion_message": "Rechnung erfolgreich erstellt",
|
||||
"convert_to_invoice": "Konvertieren in Rechnung",
|
||||
"created_message": "Kostenvoranschlag erfolgreich erstellt",
|
||||
"customer": "KUNDEN",
|
||||
"date": "Datum",
|
||||
"days": "{days} Tage",
|
||||
"declined": "Abgelehnt",
|
||||
"deleted_message": "Kostenvoranschlag erfolgreich gelöscht | Kostenvoranschläge erfolgreich gelöscht",
|
||||
"discount": "Rabatt",
|
||||
"draft": "Entwurf",
|
||||
"due_date": "Fälligkeit",
|
||||
"edit_estimate": "Kostenvoranschlag ändern",
|
||||
"errors": {
|
||||
"required": "Feld ist erforderlich"
|
||||
},
|
||||
"estimate": "Kostenvoranschlag | Kostenvoranschläge",
|
||||
"estimate_number": "Kostenvoran. Nummer",
|
||||
"estimate_template": "Vorlage",
|
||||
"estimates_list": "Liste Kostenvoranschläge",
|
||||
"expiry_date": "Zahlungsziel",
|
||||
"item": {
|
||||
"amount": "Summe",
|
||||
"description": "Beschreibung",
|
||||
"discount": "Rabatt",
|
||||
"price": "Preis",
|
||||
"quantity": "Menge",
|
||||
"select_an_item": "Wählen Sie einen Artikel",
|
||||
"sub_total": "Zwischensumme",
|
||||
"tax": "Steuer",
|
||||
"title": "Titel",
|
||||
"total": "Gesamt",
|
||||
"total_discount": "Rabatt Gesamt",
|
||||
"type_item_description": "Artikel Beschreibung (optional)"
|
||||
},
|
||||
"items": "Artikel",
|
||||
"list_of_estimates": "Dieser Abschnitt enthält die Liste der Kostenvoranschläge.",
|
||||
"mark_as_accepted": "Markiert als angenommen",
|
||||
"mark_as_rejected": "Markiert als abgelehnt",
|
||||
"mark_as_sent": "Als gesendet markieren",
|
||||
"mark_as_sent_successfully": "Kostenvoranschlag als gesendet markiert.",
|
||||
"marked_as_accepted_message": "Kostenvoranschlag als angenommen markiert",
|
||||
"marked_as_rejected_message": "Kostenvoranschlag als abgelehnt markiert",
|
||||
"months": "{months} Monat",
|
||||
"new_estimate": "Neuer Kostenvoranschlag",
|
||||
"no_estimates": "Keine Kostenvoranschläge vorhanden!",
|
||||
"no_matching_estimates": "Es gibt keine übereinstimmenden Kostenvoranschläge!",
|
||||
"notes": "Hinweise",
|
||||
"number": "ANZAHL",
|
||||
"paid": "Bezahlt",
|
||||
"partially_paid": "Teilweise bezahlt",
|
||||
"record_payment": "Zahlung erfassen",
|
||||
"ref_no": "REF. - NR.",
|
||||
"ref_number": "Ref-Nummer",
|
||||
"save_estimate": "Kostenvoranschlag speichern",
|
||||
"send_estimate": "Kostenvoranschlag senden",
|
||||
"send_estimate_successfully": "Kostenvoranschlag erfolgreich gesendet",
|
||||
"sent": "Gesendet",
|
||||
"something_went_wrong": "Da ging etwas schief",
|
||||
"status": "Status",
|
||||
"sub_total": "Zwischensumme",
|
||||
"tax": "Steuer",
|
||||
"title": "Kostenvoranschläge",
|
||||
"total": "Gesamt",
|
||||
"unpaid": "Unbezahlte",
|
||||
"update_Estimate": "Kostenvoranschlag aktualisieren",
|
||||
"updated_message": "Kostenvoranschlag erfolgreich aktualisiert",
|
||||
"user_email_does_not_exist": "Benutzer-E-Mail nicht vorhanden",
|
||||
"years": "{years} Jahre"
|
||||
},
|
||||
"expenses": {
|
||||
"action": "Aktion",
|
||||
"add_expense": "Aufwendung hinzufügen",
|
||||
"add_new_expense": "Neue Aufwendung hinzufügen",
|
||||
"amount": "Summe",
|
||||
"categories": {
|
||||
"actions": "Aktionen",
|
||||
"add_category": "Kategorie hinzufügen",
|
||||
"amount": "Summe",
|
||||
"categories_list": "Liste der Kategorien",
|
||||
"category": "Kategorie | Kategorien",
|
||||
"description": "Beschreibung",
|
||||
"name": "Name",
|
||||
"new_category": "Neue Kategorie",
|
||||
"select_a_category": "Wählen Sie eine Kategorie",
|
||||
"title": "Titel"
|
||||
},
|
||||
"category": "Kategorie",
|
||||
"category_id": "Kategorie-Id",
|
||||
"confirm_delete": "Sie können diese Ausgabe nicht wiederherstellen. | Sie können diese Ausgaben nicht wiederherstellen.",
|
||||
"contact": "Kontakt",
|
||||
"created_message": "Aufwand erfolgreich erstellt",
|
||||
"date": "Aufwandsdatum",
|
||||
"deleted_message": "Aufwand erfolgreich gelöscht | Aufwand erfolgreich gelöscht",
|
||||
"description": "Beschreibung",
|
||||
"download_receipt": "Quittung herunterladen",
|
||||
"edit_expense": "Aufwendung ändern",
|
||||
"expense": "Aufwendung | Aufwendungen",
|
||||
"expense_date": "Datum",
|
||||
"expense_title": "Titel",
|
||||
"expenses_list": "Liste der Ausgaben",
|
||||
"from_date": "Von Datum",
|
||||
"list_of_expenses": "Dieser Abschnitt enthält die Liste der Ausgaben.",
|
||||
"new_expense": "Neue Aufwendung",
|
||||
"no_expenses": "Noch keine Ausgaben!",
|
||||
"note": "Hinweis",
|
||||
"receipt": "Eingang",
|
||||
"save_expense": "Aufwendung speichern",
|
||||
"title": "Aufwendungen/Ausgaben",
|
||||
"to_date": "bis Datum",
|
||||
"update_expense": "Aufwendung aktualisieren",
|
||||
"updated_message": "Aufwand erfolgreich aktualisiert"
|
||||
},
|
||||
"general": {
|
||||
"action_failed": "Aktion fehlgeschlagen",
|
||||
"actions": "Aktionen",
|
||||
"add_new_item": "Artikel hinzufügen",
|
||||
"all": "Alle",
|
||||
"are_you_sure": "Sind Sie sicher?",
|
||||
"back_to_login": "Zurück zum Login?",
|
||||
"bill_to": "Rechnungsempfänger",
|
||||
"bytefury": "Bytefury",
|
||||
"cancel": "Abrechen",
|
||||
"choose": "Wählen",
|
||||
"choose_file": "Klicken Sie hier, um eine Datei auszuwählen",
|
||||
"choose_template": "Wählen Sie eine Vorlage",
|
||||
"clear_all": "Alle entfernen",
|
||||
"delete": "Löschen",
|
||||
"discount": "RABATT",
|
||||
"download": "Download",
|
||||
"download_pdf": "Download PDF",
|
||||
"draft": "Entwurf",
|
||||
"due": "Fällig",
|
||||
"edit": "Ändern",
|
||||
"filter": "Filter",
|
||||
"fixed": "Behoben",
|
||||
"four_zero_four": "Vier hundert vier",
|
||||
"from": "Von",
|
||||
"from_date": "Von Datum",
|
||||
"go_back": "zurück",
|
||||
"go_home": "Geh zurück",
|
||||
"home": "Startseite",
|
||||
"list_is_empty": "Liste ist leer.",
|
||||
"no_tax_found": "Kein Steuersatz gefunden!",
|
||||
"of": "von",
|
||||
"percentage": "Prozentsatz",
|
||||
"powered_by": "Powered by",
|
||||
"remove": "Entfernen",
|
||||
"save": "Speichern",
|
||||
"search": "Suchen",
|
||||
"select_a_status": "Status wählen",
|
||||
"select_a_tax": "Steuersatz wählen",
|
||||
"select_all": "Alle auswählen",
|
||||
"select_city": "Stadt wählen",
|
||||
"select_country": "Land wählen",
|
||||
"select_state": "Bundesland wählen",
|
||||
"sent": "Gesendet",
|
||||
"setting_updated": "Einstellungen erfolgreich aktualisiert",
|
||||
"ship_to": "Versand ein",
|
||||
"showing": "Anzeigen",
|
||||
"street_1": "Straße",
|
||||
"street_2": "Zusatz Strasse",
|
||||
"subtotal": "ZWISCHENSUMME",
|
||||
"tax": "Steuer",
|
||||
"to": "bis",
|
||||
"to_date": "bis Datum",
|
||||
"total_amount": "GESAMTSUMME",
|
||||
"update": "Update",
|
||||
"view": "Anzeigen",
|
||||
"view_pdf": "PDF anzeigen",
|
||||
"you_got_lost": "Hoppla! Du hast dich verirrt!"
|
||||
},
|
||||
"invoices": {
|
||||
"action": "Aktion",
|
||||
"add_item": "Fügen Sie ein Artikel hinzu",
|
||||
"add_new_invoice": "Neue Rechnung hinzufügen",
|
||||
"add_new_tax": "Neuen Steuersatz hinzufügen",
|
||||
"add_tax": "Steuersatz hinzufügen",
|
||||
"all": "Alle",
|
||||
"amount": "Summe",
|
||||
"amount_due": "OFFENER BETRAG",
|
||||
"confirm_delete": "Sie können diese Rechnung nicht wiederherstellen. | Sie können diese Rechnungen nicht wiederherstellen.",
|
||||
"confirm_send": "Diese Rechnung wird per E-Mail an den Kunden gesendet",
|
||||
"confirm_send_invoice": "Diese Rechnung wird per E-Mail an den Kunden gesendet",
|
||||
"contact": "Kontakt",
|
||||
"created_message": "Rechnung erfolgreich erstellt",
|
||||
"customer": "KUNDEN",
|
||||
"date": "Datum",
|
||||
"days": "{days} Tage",
|
||||
"deleted_message": "Rechnung erfolgreich gelöscht | Rechnungen erfolgreich gelöscht",
|
||||
"discount": "Rabatt",
|
||||
"due_date": "Fälligkeit",
|
||||
"edit_invoice": "Rechnung bearbeiten",
|
||||
"invalid_due_amount_message": "Der Gesamtrechnungsbetrag darf nicht kleiner sein als der für diese Rechnung bezahlte Gesamtbetrag. Bitte aktualisieren Sie die Rechnung oder löschen Sie die zugehörigen Zahlungen um fortzufahren.",
|
||||
"invoice": "Rechnung | Rechnungen",
|
||||
"invoice_date": "Rechnungsdatum",
|
||||
"invoice_mark_as_sent": "Diese Rechnung wird als gesendet markiert",
|
||||
"invoice_number": "Rechnungsnummer",
|
||||
"invoice_template": "Rechnungs-Vorlage",
|
||||
"invoices_list": "Liste der Rechnungen",
|
||||
"item": {
|
||||
"amount": "Summe",
|
||||
"description": "Beschreibung",
|
||||
"discount": "Rabatt",
|
||||
"price": "Preis",
|
||||
"quantity": "Menge",
|
||||
"select_an_item": "Geben Sie oder wählen Sie ein Artikel",
|
||||
"sub_total": "Zwischensumme",
|
||||
"tax": "Steuer",
|
||||
"title": "Titel",
|
||||
"total": "Gesamt",
|
||||
"total_discount": "Rabatt Gesamt",
|
||||
"type_item_description": "Artikel Beschreibung (optional)"
|
||||
},
|
||||
"list_of_invoices": "Dieser Abschnitt enthält die Liste der Rechnungen.",
|
||||
"mark_as_sent": "Als gesendet markieren",
|
||||
"mark_as_sent_successfully": "Rechnung gekennzeichnet als erfolgreich gesendet",
|
||||
"marked_as_sent_message": "Rechnung als erfolgreich gesendet markiert",
|
||||
"months": "{months} Monat",
|
||||
"new_invoice": "Neue Rechnung",
|
||||
"no_invoices": "Keine Rechnungen vorhanden!",
|
||||
"no_matching_invoices": "Es gibt keine entsprechenden Rechnungen!",
|
||||
"notes": "Hinweise",
|
||||
"number": "ANZAHL",
|
||||
"paid": "Bezahlt",
|
||||
"paid_status": "BEZAHLT-STATUS",
|
||||
"partially_paid": "Teilzahlung",
|
||||
"payment_attached_message": "Einer der ausgewählten Rechnungen ist bereits eine Zahlung zugeordnet. Stellen Sie sicher, dass Sie zuerst die angehängten Zahlungen löschen, um mit dem Entfernen fortzufahren",
|
||||
"record_payment": "Zahlung erfassen",
|
||||
"ref_no": "REF. - NR.",
|
||||
"ref_number": "Ref-Nummer",
|
||||
"save_invoice": "Rechnung speichern",
|
||||
"select_invoice": "Wählen Sie eine Rechnung",
|
||||
"send_invoice": "Rechnung senden",
|
||||
"send_invoice_successfully": "Rechnung erfolgreich versendet",
|
||||
"something_went_wrong": "Da ist etwas schief gelaufen",
|
||||
"status": "Status",
|
||||
"sub_total": "Zwischensumme",
|
||||
"template": "Vorlage",
|
||||
"title": "Rechnungen",
|
||||
"total": "Gesamt",
|
||||
"unpaid": "Unbezahlte",
|
||||
"update_expense": "Kosten aktualisieren",
|
||||
"update_invoice": "Rechnung ändern",
|
||||
"updated_message": "Rechnung erfolgreich aktualisiert",
|
||||
"user_email_does_not_exist": "Benutzer-E-Mail existiert nicht",
|
||||
"view": "Anzeigen",
|
||||
"years": "{years} Jahre"
|
||||
},
|
||||
"items": {
|
||||
"action": "Aktion",
|
||||
"add_item": "Artikel hinzufügen",
|
||||
"add_new_item": "Neuen Artikel hinzufügen",
|
||||
"added_on": "Hinzugefügt am",
|
||||
"confirm_delete": "Sie können diesen Artikel nicht wiederherstellen | Sie können diese Artikel nicht wiederherstellen",
|
||||
"created_message": "Artikel erfolgreich erstellt",
|
||||
"date_of_creation": "Erstellt am",
|
||||
"deleted_message": "Artikel erfolgreich gelöscht | Artikel erfolgreich gelöscht",
|
||||
"description": "Beschreibung",
|
||||
"edit_item": "Artikel bearbeiten",
|
||||
"item": "Artikel | Artikel",
|
||||
"item_attached_message": "Ein Artikel der bereits verwendet wird kann nicht gelöscht werden",
|
||||
"items_list": "Artikel-Liste",
|
||||
"list_of_items": "Dieser Abschnitt enthält die Liste der Artikel.",
|
||||
"name": "Name",
|
||||
"new_item": "Neuer Artikel",
|
||||
"no_items": "Keine Artikel vorhanden!",
|
||||
"price": "Preis",
|
||||
"save_item": "Artikel speichern",
|
||||
"select_a_unit": "wählen Sie die Einheit",
|
||||
"title": "Artikel",
|
||||
"unit": "Einheit",
|
||||
"update_item": "Artikel ändern",
|
||||
"updated_message": "Artikel erfolgreich aktualisiert"
|
||||
},
|
||||
"layout_login": {
|
||||
"copyright_crater": "Copyright @ Crater - 2019",
|
||||
"crater_help": "Crater helps you track expenses, record payments & generate beautiful",
|
||||
"for_freelancer": "for Freelancers &",
|
||||
"invoices_and_estimates": "invoices & estimates with ability to choose multiple templates.",
|
||||
"small_businesses": "Small Businesses ",
|
||||
"super_simple_invoicing": "Super Simple Invoicing"
|
||||
},
|
||||
"login": {
|
||||
"email": "E-Mail",
|
||||
"enter_email": "Geben Sie Ihre E-Mail ein",
|
||||
"enter_password": "Geben Sie das Passwort ein",
|
||||
"forgot_password": "Passwort vergessen?",
|
||||
"login": "Anmelden",
|
||||
"login_placeholder": "mail@example.com",
|
||||
"or_signIn_with": "oder Anmelden mit",
|
||||
"password": "Passwort",
|
||||
"password_reset_successfully": "Passwort erfolgreich zurückgesetzt",
|
||||
"register": "Registrieren",
|
||||
"reset_password": "Passwort zurücksetzen",
|
||||
"retype_password": "Passwort bestätigen"
|
||||
},
|
||||
"navigation": {
|
||||
"customers": "Kunden",
|
||||
"dashboard": "Übersicht",
|
||||
"estimates": "Kostenvoranschläge",
|
||||
"expenses": "Kosten",
|
||||
"invoices": "Rechnungen",
|
||||
"items": "Artikel",
|
||||
"logout": "Abmelden",
|
||||
"payments": "Zahlungen",
|
||||
"reports": "Berichte",
|
||||
"settings": "Einstellungen"
|
||||
},
|
||||
"payments": {
|
||||
"action": "Aktion",
|
||||
"add_new_payment": "Neue Zahlung hinzufügen",
|
||||
"add_payment": "Zahlung hinzufügen",
|
||||
"amount": "Summe",
|
||||
"confirm_delete": "Sie können diese Zahlung nicht wiederherstellen. | Sie können diese Zahlungen nicht wiederherstellen.",
|
||||
"created_message": "Zahlung erfolgreich erstellt",
|
||||
"customer": "Kunden",
|
||||
"date": "Datum",
|
||||
"deleted_message": "Zahlung erfolgreich gelöscht | Zahlungen erfolgreich gelöscht",
|
||||
"edit_payment": "Zahlung bearbeiten",
|
||||
"invalid_amount_message": "Zahlungsbetrag ist ungültig",
|
||||
"invoice": "Rechnung",
|
||||
"list_of_payments": "Dieser Abschnitt enthält die Liste der Zahlungen.",
|
||||
"new_payment": "Neue Zahlung",
|
||||
"no_payments": "Keine Zahlungen vorhanden!",
|
||||
"note": "Hinweis",
|
||||
"payment": "Zahlung | Zahlungen",
|
||||
"payment_mode": "Zahlungsart",
|
||||
"payment_number": "Zahlungsnummer",
|
||||
"payments_list": "Liste der Zahlungen",
|
||||
"record_payment": "Zahlung eintragen",
|
||||
"save_payment": "Zahlung speichern",
|
||||
"select_payment_mode": "Wählen Sie den Zahlungsmodus",
|
||||
"title": "Zahlungen",
|
||||
"update_payment": "Zahlung ändern",
|
||||
"updated_message": "Zahlung erfolgreich aktualisiert",
|
||||
"view_payment": "Zahlung anzeigen"
|
||||
},
|
||||
"reports": {
|
||||
"download_pdf": "Download PDF",
|
||||
"errors": {
|
||||
"required": "Feld ist erforderlich"
|
||||
},
|
||||
"estimates": {
|
||||
"amount": "Summe",
|
||||
"contact_name": "Ansprechpartner",
|
||||
"due_date": "Fälligkeit",
|
||||
"estimate": "Kostenvoranschlag",
|
||||
"estimate_date": "Datum Kostenvoranschlag",
|
||||
"estimate_number": "Kostenvoranschlag-Nr.",
|
||||
"ref_number": "Ref-Nummer",
|
||||
"status": "Status"
|
||||
},
|
||||
"expenses": {
|
||||
"amount": "Summe",
|
||||
"category": "Kategorie",
|
||||
"date": "Datum",
|
||||
"date_range": "Datumsbereich auswählen",
|
||||
"expenses": "Aufwendungen",
|
||||
"from_date": "Ab Datum",
|
||||
"to_date": "bis Datum"
|
||||
},
|
||||
"from_date": "Ab Datum",
|
||||
"invoices": {
|
||||
"amount": "Summe",
|
||||
"contact_name": "Ansprechpartner",
|
||||
"due_date": "Fälligkeit",
|
||||
"invoice": "Rechnung",
|
||||
"invoice_date": "Rechnungsdatum",
|
||||
"status": "Status"
|
||||
},
|
||||
"paid": "Bezahlt",
|
||||
"profit_loss": {
|
||||
"date_range": "Datumsbereich auswählen",
|
||||
"from_date": "Ab Datum",
|
||||
"profit_loss": "Gewinn & Verlust",
|
||||
"to_date": "bis Datum"
|
||||
},
|
||||
"report": "Bericht | Berichte",
|
||||
"sales": {
|
||||
"date_range": "Datumsbereich auswählen",
|
||||
"from_date": "Ab Datum",
|
||||
"report_type": "Berichtstyp",
|
||||
"sales": "Vertrieb",
|
||||
"to_date": "bis Datum"
|
||||
},
|
||||
"status": "Status",
|
||||
"taxes": {
|
||||
"date_range": "Datumsbereich auswählen",
|
||||
"from_date": "Ab Datum",
|
||||
"taxes": "Steuern",
|
||||
"to_date": "bis Datum"
|
||||
},
|
||||
"title": "Bericht",
|
||||
"to_date": "bis Datum",
|
||||
"unpaid": "Unbezahlt",
|
||||
"update_report": "Bericht aktualisieren",
|
||||
"view_pdf": "PDF anzeigen"
|
||||
},
|
||||
"settings": {
|
||||
"account_settings": {
|
||||
"account_settings": "Konto-Einstellungen",
|
||||
"confirm_password": "Kennwort Bestätigen",
|
||||
"email": "E-Mail",
|
||||
"name": "Name",
|
||||
"password": "Passwort",
|
||||
"profile_picture": "Profil Bild",
|
||||
"save": "Speichern",
|
||||
"section_description": "Sie können Ihren Namen, Ihre E-Mail-Adresse und Ihr Passwort mit dem folgenden Formular aktualisieren.",
|
||||
"updated_message": "Kontoeinstellungen erfolgreich aktualisiert"
|
||||
},
|
||||
"company_info": {
|
||||
"address": "Adresse",
|
||||
"city": "Stadt",
|
||||
"company_info": "Firmeninfo",
|
||||
"company_logo": "Firmenlogo",
|
||||
"company_name": "Name des Unternehmens",
|
||||
"country": "Land",
|
||||
"phone": "Telefon",
|
||||
"save": "Speichern",
|
||||
"section_description": "Informationen zu Ihrem Unternehmen, die auf Rechnungen, Kostenvoranschlägen und anderen von Crater erstellten Dokumenten angezeigt werden.",
|
||||
"state": "Bundesland",
|
||||
"updated_message": "Unternehmensinformationen wurden erfolgreich aktualisiert",
|
||||
"zip": "PLZ"
|
||||
},
|
||||
"currencies": {
|
||||
"action": "Aktion",
|
||||
"add_currency": "Währung einfügen",
|
||||
"code": "Code",
|
||||
"currencies_list": "Währungen Liste",
|
||||
"currency": "Währung | Währungen",
|
||||
"decimal_separator": "Decimal-Separator",
|
||||
"left": "Links",
|
||||
"name": "Name",
|
||||
"position": "Position",
|
||||
"position_of_symbol": "Position des Währungssymbol",
|
||||
"precision": "Präzision",
|
||||
"right": "Rechts",
|
||||
"select_currency": "Währung wählen",
|
||||
"symbol": "Symbol",
|
||||
"thousand_separator": "Tausendertrennzeichen",
|
||||
"title": "Währungen"
|
||||
},
|
||||
"customization": {
|
||||
"addresses": {
|
||||
"address": "Adresse",
|
||||
"address_setting_updated": "Adresse-Einstellung erfolgreich aktualisiert",
|
||||
"address_street_1": "Strasse",
|
||||
"address_street_2": "Zusatz Strasse",
|
||||
"city": "Stadt",
|
||||
"company_address": "Firma Adresse",
|
||||
"company_name": "Name des Unternehmens",
|
||||
"contact": "Kontakt",
|
||||
"country": "Land",
|
||||
"customer_billing_address": "Rechnungsadresse des Kunden",
|
||||
"customer_shipping_address": "Versand-Adresse des Kunden",
|
||||
"display_name": "Anzeigename",
|
||||
"email": "E-Mail",
|
||||
"insert_fields": "Felder einfügen",
|
||||
"name": "Name",
|
||||
"phone": "Telefon",
|
||||
"primary_contact_name": "Ansprechpartner",
|
||||
"section_description": "Sie können die Rechnungsadresse und das Versandadressenformat des Kunden festlegen (nur in PDF angezeigt). ",
|
||||
"state": "Bundesland",
|
||||
"title": "Adressen",
|
||||
"website": "Website",
|
||||
"zip_code": "PLZ"
|
||||
},
|
||||
"customization": "Anpassung",
|
||||
"estimates": {
|
||||
"autogenerate_estimate_number": "Kostenvoranschlagsnummer automatisch generieren",
|
||||
"enter_estimate_prefix": "Geben Sie das Kostenvoranschlag Präfix ein",
|
||||
"estimate_prefix": "Kostenvoranschlag Präfix",
|
||||
"estimate_setting_description": "Deaktivieren Sie diese Option, wenn Sie nicht jedes Mal, wenn Sie einen neue Kostenvoranschlag erstellen, automatisch eine Schätzung generieren möchten.",
|
||||
"estimate_setting_updated": "Einstellungen Kostenvoranschläge erfolgreich aktualisiert",
|
||||
"estimate_settings": "Einstellungen Kostenvoranschlag",
|
||||
"title": "Kostenvoranschläge"
|
||||
},
|
||||
"invoices": {
|
||||
"autogenerate_invoice_number": "Rechnungsnummer automatisch generieren",
|
||||
"enter_invoice_prefix": "Rechnungspräfix eingeben",
|
||||
"invoice_prefix": "Rechnung Präfix",
|
||||
"invoice_setting_description": "Deaktivieren Sie diese Option, wenn Sie Rechnungsnummern nicht jedes Mal automatisch generieren möchten, wenn Sie eine neue Rechnung erstellen.",
|
||||
"invoice_setting_updated": "Rechnungseinstellung erfolgreich aktualisiert",
|
||||
"invoice_settings": "Rechnungseinstellungen",
|
||||
"notes": "Hinweise",
|
||||
"terms_and_conditions": "Allgemeine Geschäftsbedingungen",
|
||||
"title": "Rechnungen"
|
||||
},
|
||||
"payments": {
|
||||
"autogenerate_payment_number": "Zahlungsnummer automatisch generieren",
|
||||
"enter_payment_prefix": "Zahlungspräfix eingeben",
|
||||
"payment_prefix": "Zahlung Präfix",
|
||||
"payment_setting_description": "Deaktivieren Sie diese Option, wenn Sie nicht jedes Mal, wenn Sie eine neue Zahlung erstellen, automatisch Zahlungsnummern generieren möchten.",
|
||||
"payment_setting_updated": "Zahlungseinstellung erfolgreich aktualisiert",
|
||||
"payment_settings": "Zahlung Einstellungen",
|
||||
"title": "Zahlungen"
|
||||
},
|
||||
"save": "Speichern",
|
||||
"updated_message": "Unternehmensinformationen wurden erfolgreich aktualisiert"
|
||||
},
|
||||
"date_format": "Datum-Format",
|
||||
"expense_category": {
|
||||
"action": "Aktion",
|
||||
"add_new_category": "Neue Kategorie hinzufügen",
|
||||
"already_in_use": "Kategorie wird bereits verwendet",
|
||||
"category_description": "Beschreibung",
|
||||
"category_name": "Kategorie Name",
|
||||
"confirm_delete": "Sie können diese Ausgabenkategorie nicht wiederherstellen",
|
||||
"created_message": "Ausgabenkategorie erfolgreich erstellt",
|
||||
"deleted_message": "Ausgabenkategorie erfolgreich gelöscht",
|
||||
"description": "Für das Hinzufügen von Ausgabeneinträgen sind Kategorien erforderlich. Sie können diese Kategorien nach Ihren Wünschen hinzufügen oder entfernen.",
|
||||
"title": "Kategorien Kosten",
|
||||
"updated_message": "Ausgabenkategorie erfolgreich aktualisiert"
|
||||
},
|
||||
"general": "Allgemeine",
|
||||
"language": "Sprache",
|
||||
"mail": {
|
||||
"driver": "E-Mail Treiber",
|
||||
"encryption": "E-Mail-Verschlüsselung",
|
||||
"from_mail": "Von E-Mail-Adresse",
|
||||
"from_name": "Von E-Mail-Namen",
|
||||
"host": "E-Mail Mailserver",
|
||||
"mail_config": "E-Mail-Konfiguration",
|
||||
"mail_config_desc": "Unten finden Sie das Formular zum Konfigurieren des E-Mail-Treibers zum Senden von E-Mails über die App. Sie können auch Drittanbieter wie Sendgrid, SES usw. konfigurieren.",
|
||||
"mailgun_domain": "Domain",
|
||||
"mailgun_endpoint": "Mailgun-Endpunkt",
|
||||
"mailgun_secret": "Mailgun Verschlüsselung",
|
||||
"password": "E-Mail-Kennwort",
|
||||
"port": "E-Mail Port",
|
||||
"secret": "Verschlüsselung",
|
||||
"ses_key": "SES-Taste",
|
||||
"ses_secret": "SES Verschlüsselung",
|
||||
"username": "E-Mail-Benutzername"
|
||||
},
|
||||
"menu_title": {
|
||||
"account_settings": "Konto-Einstellungen",
|
||||
"company_information": "Informationen zum Unternehmen",
|
||||
"customization": "Anpassung",
|
||||
"expense_category": "Ausgabenkategorien",
|
||||
"notifications": "Benachrichtigungen",
|
||||
"preferences": "Einstellungen",
|
||||
"tax_types": "Steuersätze",
|
||||
"update_app": "Update App"
|
||||
},
|
||||
"notification": {
|
||||
"description": "Welche E-Mail-Benachrichtigungen möchten Sie erhalten wenn sich etwas ändert?",
|
||||
"email": "Benachrichtigungen senden an",
|
||||
"email_save_message": "Email erfolgreich gespeichert",
|
||||
"estimate_viewed": "Kostenvoranschlag angesehen",
|
||||
"estimate_viewed_desc": "Wenn Ihr Kunde den gesendeten Kostenvoranschlag anzeigt bekommt.",
|
||||
"invoice_viewed": "Rechnung angezeigt",
|
||||
"invoice_viewed_desc": "Wenn Ihr Kunde die gesendete Rechnung anzeigt bekommt.",
|
||||
"please_enter_email": "Bitte E-Mail eingeben",
|
||||
"save": "Speichern",
|
||||
"title": "Benachrichtigung"
|
||||
},
|
||||
"pdf": {
|
||||
"footer_text": "Fußzeile Text",
|
||||
"pdf_layout": "PDF-Layout",
|
||||
"title": "PDF-Einstellung"
|
||||
},
|
||||
"preferences": {
|
||||
"currency": "Währung",
|
||||
"date_format": "Datum-Format",
|
||||
"discount_per_item": "Rabatt pro Artikel ",
|
||||
"discount_setting": "Einstellung Rabatt",
|
||||
"discount_setting_description": "Aktivieren Sie diese Option, wenn Sie einzelnen Rechnungspositionen einen Rabatt hinzufügen möchten. Standardmäßig wird der Rabatt direkt zur Rechnung hinzugefügt.",
|
||||
"fiscal_year": "Geschäftsjahr",
|
||||
"general_settings": "Standardeinstellungen für das System.",
|
||||
"language": "Sprache",
|
||||
"preference": "Präferenz | Präferenzen",
|
||||
"save": "Speichern",
|
||||
"select_date_formate": "select Date Formate",
|
||||
"select_financial_year": "Geschäftsjahr auswählen",
|
||||
"select_language": "Sprache auswählen",
|
||||
"select_time_zone": "Zeitzone auswählen",
|
||||
"time_zone": "Zeitzone",
|
||||
"updated_message": "Einstellungen erfolgreich aktualisiert"
|
||||
},
|
||||
"primary_currency": "Primäre Währung",
|
||||
"setting": "Einstellung | Einstellungen",
|
||||
"tax_types": {
|
||||
"action": "Aktion",
|
||||
"add_new_tax": "Neuen Steuersatz hinzufügen",
|
||||
"add_tax": "Steuersätze hinzufügen",
|
||||
"already_in_use": "Steuersatz wird bereits verwendet",
|
||||
"compound_tax": "Compound Tax",
|
||||
"confirm_delete": "Sie können diesen Steuersatz nicht wiederherstellen",
|
||||
"created_message": "Steuersatz erfolgreich erstellt",
|
||||
"deleted_message": "Steuersatz erfolgreich gelöscht",
|
||||
"description": "Sie können Steuern nach Belieben hinzufügen oder entfernen. Crater unterstützt Steuern auf einzelne Artikel sowie auf die Rechnung.",
|
||||
"percent": "Prozent",
|
||||
"tax_name": "Name des Steuersatzes",
|
||||
"tax_per_item": "Steuersatz pro Artikel",
|
||||
"tax_setting_description": "Aktivieren Sie diese Option, wenn Sie den Steuersatz zu einzelnen Rechnungspositionen hinzufügen möchten. Standardmäßig wird der Steuersatz direkt zur Rechnung hinzugefügt.",
|
||||
"tax_settings": "Einstellungen Steuersatz",
|
||||
"title": "Steuersätze",
|
||||
"updated_message": "Steuersatz erfolgreich aktualisiert"
|
||||
},
|
||||
"timezone": "Zeitzone",
|
||||
"title": "Einstellungen",
|
||||
"update_app": {
|
||||
"avail_update": "Neues Update verfügbar",
|
||||
"check_update": "Nach Updates suchen",
|
||||
"current_version": "Aktuelle Version",
|
||||
"description": "Sie können Crater ganz einfach aktualisieren, indem Sie auf die Schaltfläche unten klicken, um nach einem neuen Update zu suchen.",
|
||||
"latest_message": "Kein Update verfügbar! Du bist auf der neuesten Version.",
|
||||
"next_version": "Nächste Version",
|
||||
"progress_text": "Es dauert nur ein paar Minuten. Bitte aktualisieren Sie den Bildschirm nicht und schließen Sie das Fenster nicht, bevor das Update abgeschlossen ist.",
|
||||
"title": "Update App",
|
||||
"update": "Jetzt aktualisieren",
|
||||
"update_progress": "Update läuft ...",
|
||||
"update_success": "App wurde aktualisiert! Bitte warten Sie, während Ihr Browserfenster automatisch neu geladen wird."
|
||||
},
|
||||
"user_profile": {
|
||||
"confirm_password": "Kennwort bestätigen",
|
||||
"email": "E-Mail",
|
||||
"name": "Name",
|
||||
"password": "Passwort"
|
||||
}
|
||||
},
|
||||
"tax_types": {
|
||||
"compound_tax": "zusammengesetzte Steuer",
|
||||
"description": "Beschreibung",
|
||||
"name": "Name",
|
||||
"percent": "Prozent"
|
||||
},
|
||||
"validation": {
|
||||
"address_maxlength": "Die Adresse sollte nicht länger als 255 Zeichen sein.",
|
||||
"amount_maxlength": "Der Betrag sollte nicht größer als 20 Ziffern sein.",
|
||||
"amount_minvalue": "Betrag sollte größer als 0 sein.",
|
||||
"characters_only": "Nur Zeichen.",
|
||||
"description_maxlength": "Die Beschreibung sollte nicht länger als 255 Zeichen sein.",
|
||||
"email_already_taken": "Die E-Mail ist bereits vergeben.",
|
||||
"email_does_not_exist": "Benutzer mit der angegebenen E-Mail existiert nicht",
|
||||
"email_incorrect": "Falsche E-Mail.",
|
||||
"item_unit_already_taken": "Die Artikeleinheit wurde bereits vergeben",
|
||||
"payment_mode_already_taken": "Der Zahlungsmodus wurde bereits verwendet",
|
||||
"enter_valid_tax_rate": "Geben Sie einen gültige Steuersatz ein",
|
||||
"invalid_url": "Ungültige URL (Bsp.: http://www.crater.com)",
|
||||
"maximum_options_error": "Maximal {max} Optionen ausgewählt. Entfernen Sie zuerst eine ausgewählte Option, um eine andere auszuwählen.",
|
||||
"name_min_length": "Name muss mindestens {count} Zeichen enthalten.",
|
||||
"not_yet": "Noch erhalten? Erneut senden",
|
||||
"notes_maxlength": "Notizen sollten nicht länger als 255 Zeichen sein.",
|
||||
"numbers_only": "Nur Zahlen.",
|
||||
"password_incorrect": "Passwörter müssen identisch sein",
|
||||
"password_length": "Passwort muss {count} Zeichen lang sein.",
|
||||
"password_min_length": "Password muß {count} Zeichen enthalten",
|
||||
"payment_greater_than_due_amount": "Die eingegebene Zahlung ist mehr als der fällige Betrag dieser Rechnung.",
|
||||
"payment_greater_than_zero": "Die Zahlung muss größer als 0 sein.",
|
||||
"prefix_maxlength": "Das Präfix sollte nicht länger als 5 Zeichen sein.",
|
||||
"price_greater_than_zero": "Preis muss größer als 0 sein.",
|
||||
"price_maxlength": "Der Preis sollte nicht größer als 20 Ziffern sein.",
|
||||
"price_minvalue": "Der Preis sollte größer als 0 sein.",
|
||||
"qty_must_greater_than_zero": "Die Menge muss größer als 0 sein.",
|
||||
"quantity_maxlength": "Die Menge sollte nicht größer als 20 Ziffern sein.",
|
||||
"ref_number_maxlength": "Ref Number sollte nicht länger als 255 Zeichen sein.",
|
||||
"required": "Feld ist erforderlich",
|
||||
"send_reset_link": "Link zum Zurücksetzen senden"
|
||||
},
|
||||
"wizard": {
|
||||
"account_info": "Account-Informationen",
|
||||
"account_info_desc": "Die folgenden Details werden zum Erstellen des Hauptadministratorkontos verwendet. Sie können die Details auch jederzeit nach dem Anmelden ändern.",
|
||||
"address": "Adresse",
|
||||
"city": "Stadt",
|
||||
"company_info": "Unternehmensinformationen",
|
||||
"company_info_desc": "Diese Informationen werden auf Rechnungen angezeigt. Beachten Sie, dass Sie diese später auf der Einstellungsseite bearbeiten können.",
|
||||
"company_logo": "Firmenlogo",
|
||||
"company_name": "Firmenname",
|
||||
"confirm_password": "Passwort bestätigen",
|
||||
"continue": "Weiter",
|
||||
"country": "Land",
|
||||
"currency": "Currency",
|
||||
"database": {
|
||||
"app_url": "App-URL",
|
||||
"connection": "Datenbank Verbindung",
|
||||
"database": "URL der Seite & Datenbank",
|
||||
"db_name": "Datenbank Name",
|
||||
"desc": "Erstellen Sie eine Datenbank auf Ihrem Server und legen Sie die Anmeldeinformationen mithilfe des folgenden Formulars fest.",
|
||||
"host": "Datenbank Host",
|
||||
"password": "Datenbank Passwort",
|
||||
"port": "Datenbank Port",
|
||||
"username": "Datenbank Benutzername"
|
||||
},
|
||||
"date_format": "Datumsformat",
|
||||
"email": "Email",
|
||||
"errors": {
|
||||
"connection_failed": "Datenbankverbindung fehlgeschlagen",
|
||||
"database_should_be_empty": "Datenbank sollte leer sein",
|
||||
"database_variables_save_error": "Konfiguration kann nicht in EN.env-Datei geschrieben werden. Bitte überprüfen Sie die Dateiberechtigungen.",
|
||||
"mail_variables_save_error": "E-Mail-Konfiguration fehlgeschlagen.",
|
||||
"migrate_failed": "Migration ist Fehlgeschlagen"
|
||||
},
|
||||
"fiscal_year": "Geschäftsjahr",
|
||||
"from_address": "From Address",
|
||||
"go_back": "Zurück",
|
||||
"language": "Sprache",
|
||||
"logo_preview": "Vorschau Logo",
|
||||
"mail": {
|
||||
"driver": "E-Mail-Treiber",
|
||||
"encryption": "E-Mail-Verschlüsselung",
|
||||
"from_mail": "Von E-Mail-Absenderadresse",
|
||||
"from_name": "Von E-Mail-Absendername",
|
||||
"host": "E-Mail-Host",
|
||||
"mail_config": "E-Mail-Konfiguration",
|
||||
"mail_config_desc": "Unten finden Sie das Formular zum Konfigurieren des E-Mail-Treibers zum Senden von E-Mails über die App. Sie können auch Drittanbieter wie Sendgrid, SES usw. konfigurieren.",
|
||||
"mailgun_domain": "Domain",
|
||||
"mailgun_endpoint": "Mailgun-Endpunkt",
|
||||
"mailgun_secret": "Mailgun Verschlüsselung",
|
||||
"password": "E-Mail-Passwort",
|
||||
"port": "E-Mail-Port",
|
||||
"secret": "Verschlüsselung",
|
||||
"ses_key": "SES-Taste",
|
||||
"ses_secret": "SES Verschlüsselung",
|
||||
"username": "E-Mail-Benutzername"
|
||||
},
|
||||
"name": "Name",
|
||||
"next": "Next",
|
||||
"password": "Passwort",
|
||||
"permissions": {
|
||||
"permission_confirm_desc": "Prüfung der Berechtigung der Ordner fehlgeschlagen.",
|
||||
"permission_confirm_title": "Sind Sie sicher, dass Sie fortfahren möchten?",
|
||||
"permission_desc": "Unten finden Sie eine Liste der Ordnerberechtigungen, die erforderlich sind, damit die App funktioniert. Wenn die Berechtigungsprüfung fehlschlägt, müssen Sie Ihre Ordnerberechtigungen aktualisieren.",
|
||||
"permissions": "Berechtigungen"
|
||||
},
|
||||
"phone": "Telefon",
|
||||
"preferences": "Einstellungen",
|
||||
"preferences_desc": "Standardeinstellungen für das System.",
|
||||
"req": {
|
||||
"check_req": "Anforderungen prüfen",
|
||||
"php_req_version": "Php (version {version} erforderlich)",
|
||||
"system_req": "System Anforderungen",
|
||||
"system_req_desc": "Crater hat einige Serveranforderungen. Stellen Sie sicher, dass Ihr Server die erforderliche PHP-Version und alle unten genannten Erweiterungen hat."
|
||||
},
|
||||
"save_cont": "Speichern und weiter",
|
||||
"skip": "Überspringen",
|
||||
"state": "Bundesland",
|
||||
"street": "Straße1 | Straße2",
|
||||
"success": {
|
||||
"database_variables_save_successfully": "Datenbank erfolgreich konfiguriert.",
|
||||
"mail_variables_save_successfully": "E-Mail erfolgreich konfiguriert"
|
||||
},
|
||||
"time_zone": "Zeitzone",
|
||||
"username": "Benutzername",
|
||||
"zip_code": "Postleitzahl"
|
||||
}
|
||||
}
|
||||
@ -17,11 +17,17 @@
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
"update": "Update",
|
||||
"deselect": "Deselect",
|
||||
"download": "Download",
|
||||
"from_date": "From Date",
|
||||
"to_date": "To Date",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"sort_by": "Sort By",
|
||||
"ascending": "Ascending",
|
||||
"descending": "Descending",
|
||||
"subject": "Subject",
|
||||
"message": "Message",
|
||||
"go_back": "Go Back",
|
||||
"back_to_login": "Back to Login?",
|
||||
"home": "Home",
|
||||
@ -62,6 +68,8 @@
|
||||
"four_zero_four": "404",
|
||||
"you_got_lost": "Whoops! You got Lost!",
|
||||
"go_home": "Go Home",
|
||||
"test_mail_conf": "Test Mail Configuration",
|
||||
"send_mail_successfully": "Mail sent successfully",
|
||||
|
||||
"setting_updated": "Setting updated successfully",
|
||||
"select_state": "Select state",
|
||||
@ -180,7 +188,7 @@
|
||||
"no_items": "No items yet!",
|
||||
"list_of_items": "This section will contain the list of items.",
|
||||
"select_a_unit": "select unit",
|
||||
|
||||
"taxes": "Taxes",
|
||||
"item_attached_message": "Cannot delete an item which is already in use",
|
||||
"confirm_delete": "You will not be able to recover this Item | You will not be able to recover these Items",
|
||||
"created_message": "Item created successfully",
|
||||
@ -225,7 +233,7 @@
|
||||
"record_payment": "Record Payment",
|
||||
"add_estimate": "Add Estimate",
|
||||
"save_estimate": "Save Estimate",
|
||||
"confirm_conversion": "You want to convert this Estimate into Invoice?",
|
||||
"confirm_conversion": "This estimate will be used to create a new Invoice.",
|
||||
"conversion_message": "Invoice created successful",
|
||||
"confirm_send_estimate": "This estimate will be sent via email to the customer",
|
||||
"confirm_mark_as_sent": "This estimate will be marked as sent",
|
||||
@ -329,6 +337,9 @@
|
||||
"no_matching_invoices": "There are no matching invoices!",
|
||||
"mark_as_sent_successfully": "Invoice marked as sent successfully",
|
||||
"send_invoice_successfully": "Invoice sent successfully",
|
||||
"cloned_successfully": "Invoice cloned successfully",
|
||||
"clone_invoice": "Clone Invoice",
|
||||
"confirm_clone": "This invoice will be cloned into a new Invoice",
|
||||
"item": {
|
||||
"title": "Item Title",
|
||||
"description": "Description",
|
||||
@ -394,12 +405,17 @@
|
||||
"edit_payment": "Edit Payment",
|
||||
"view_payment": "View Payment",
|
||||
"add_new_payment": "Add New Payment",
|
||||
"send_payment_receipt": "Send Payment Receipt",
|
||||
"save_payment": "Save Payment",
|
||||
"update_payment": "Update Payment",
|
||||
"payment": "Payment | Payments",
|
||||
"no_payments": "No payments yet!",
|
||||
"list_of_payments": "This section will contain the list of payments.",
|
||||
"select_payment_mode": "Select payment mode",
|
||||
"confirm_send_payment": "This payment will be sent via email to the customer",
|
||||
"send_payment_successfully": "Payment sent successfully",
|
||||
"user_email_does_not_exist": "User email does not exist",
|
||||
"something_went_wrong": "something went wrong",
|
||||
|
||||
"confirm_delete": "You will not be able to recover this Payment | You will not be able to recover these Payments",
|
||||
"created_message": "Payment created successfully",
|
||||
@ -633,7 +649,7 @@
|
||||
"notes": "Notes",
|
||||
"invoice_prefix": "Invoice Prefix",
|
||||
"invoice_settings": "Invoice Settings",
|
||||
"autogenerate_invoice_number": "Autogenerate Invoice Number",
|
||||
"autogenerate_invoice_number": "Auto-generate Invoice Number",
|
||||
"invoice_setting_description": "Disable this, If you don't wish to auto-generate invoice numbers each time you create a new invoice.",
|
||||
"enter_invoice_prefix": "Enter invoice prefix",
|
||||
"terms_and_conditions": "Terms and Conditions",
|
||||
@ -644,7 +660,7 @@
|
||||
"title": "Estimates",
|
||||
"estimate_prefix": "Estimate Prefix",
|
||||
"estimate_settings": "Estimate Settings",
|
||||
"autogenerate_estimate_number": "Autogenerate Estimate Number",
|
||||
"autogenerate_estimate_number": "Auto-generate Estimate Number",
|
||||
"estimate_setting_description": "Disable this, If you don't wish to auto-generate estimate numbers each time you create a new estimate.",
|
||||
"enter_estimate_prefix": "Enter estmiate prefix",
|
||||
"estimate_setting_updated": "Estimate Setting updated successfully"
|
||||
@ -654,10 +670,30 @@
|
||||
"title": "Payments",
|
||||
"payment_prefix": "Payment Prefix",
|
||||
"payment_settings": "Payment Settings",
|
||||
"autogenerate_payment_number": "Autogenerate Payment Number",
|
||||
"autogenerate_payment_number": "Auto-generate Payment Number",
|
||||
"payment_setting_description": "Disable this, If you don't wish to auto-generate payment numbers each time you create a new payment.",
|
||||
"enter_payment_prefix": "Enter Payment Prefix",
|
||||
"payment_setting_updated": "Payment Setting updated successfully"
|
||||
"payment_setting_updated": "Payment Setting updated successfully",
|
||||
"payment_mode": "Payment Mode",
|
||||
"add_payment_mode": "Add Payment Mode",
|
||||
"mode_name": "Mode Name",
|
||||
"payment_mode_added": "Payment Mode Added",
|
||||
"payment_mode_updated": "Payment Mode Updated",
|
||||
"payment_mode_confirm_delete":"You will not be able to recover this Payment Mode",
|
||||
"already_in_use": "Payment Mode is already in use",
|
||||
"deleted_message": "Payment Mode deleted successfully"
|
||||
},
|
||||
|
||||
"items": {
|
||||
"title": "Items",
|
||||
"units": "units",
|
||||
"add_item_unit": "Add Item Unit",
|
||||
"unit_name": "Unit Name",
|
||||
"item_unit_added": "Item Unit Added",
|
||||
"item_unit_updated": "Item Unit Updated",
|
||||
"item_unit_confirm_delete":"You will not be able to recover this Item unit",
|
||||
"already_in_use": "Item Unit is already in use",
|
||||
"deleted_message": "Item Unit deleted successfully"
|
||||
}
|
||||
},
|
||||
"account_settings": {
|
||||
@ -852,6 +888,8 @@
|
||||
"email_incorrect": "Incorrect Email.",
|
||||
"email_already_taken": "The email has already been taken.",
|
||||
"email_does_not_exist": "User with given email doesn't exist",
|
||||
"item_unit_already_taken": "This item unit name has already been taken",
|
||||
"payment_mode_already_taken": "This payment mode name has already been taken",
|
||||
"send_reset_link": "Send Reset Link",
|
||||
"not_yet": "Not yet? Send it again",
|
||||
"password_min_length": "Password must contain {count} characters",
|
||||
@ -871,10 +909,13 @@
|
||||
"amount_maxlength": "Amount should not be greater than 20 digits.",
|
||||
"amount_minvalue": "Amount should be greater than 0.",
|
||||
"description_maxlength": "Description should not be greater than 255 characters.",
|
||||
"subject_maxlength": "Subject should not be greater than 100 characters.",
|
||||
"message_maxlength": "Message should not be greater than 255 characters.",
|
||||
"maximum_options_error": "Maximum of {max} options selected. First remove a selected option to select another.",
|
||||
"notes_maxlength": "Notes should not be greater than 255 characters.",
|
||||
"address_maxlength": "Address should not be greater than 255 characters.",
|
||||
"ref_number_maxlength": "Ref Number should not be greater than 255 characters.",
|
||||
"prefix_maxlength": "Prefix should not be greater than 5 characters."
|
||||
"prefix_maxlength": "Prefix should not be greater than 5 characters.",
|
||||
"something_went_wrong": "something went wrong"
|
||||
}
|
||||
}
|
||||
|
||||
@ -784,6 +784,8 @@
|
||||
"required": "Se requiere campo",
|
||||
"email_incorrect": "Email incorrecto.",
|
||||
"email_does_not_exist": " Usuario con correo electrónico dado no existe",
|
||||
"item_unit_already_taken": "La unidad del artículo ya ha sido tomada",
|
||||
"payment_mode_already_taken": "El modo de pago ya ha sido tomado",
|
||||
"send_reset_link": "Enviar restablecer enlace",
|
||||
"not_yet": "¿Aún no? Envialo de nuevo",
|
||||
"password_min_length": "La contraseña debe contener {count} caracteres",
|
||||
|
||||
@ -787,6 +787,8 @@
|
||||
"required": "Champ requis",
|
||||
"email_incorrect": "Adresse Email incorrecte.",
|
||||
"email_does_not_exist": "L'utilisateur avec un email donné n'existe pas",
|
||||
"item_unit_already_taken": "L'unité d'article a déjà été prise",
|
||||
"payment_mode_already_taken": "Le mode de paiement a déjà été pris",
|
||||
"send_reset_link": "Envoyer le lien de réinitialisation",
|
||||
"not_yet": "Pas encore? Envoyer à nouveau",
|
||||
"password_min_length": "Le mot de passe doit contenir {nombre} caractères",
|
||||
|
||||
@ -4,6 +4,7 @@ import en from './en.json'
|
||||
import fr from './fr.json'
|
||||
import es from './es.json'
|
||||
import ar from './ar.json'
|
||||
import de from './de.json'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
@ -13,7 +14,8 @@ const i18n = new VueI18n({
|
||||
en,
|
||||
fr,
|
||||
es,
|
||||
ar
|
||||
ar,
|
||||
de
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@ import InvoiceView from './views/invoices/View.vue'
|
||||
// Payments
|
||||
import PaymentsIndex from './views/payments/Index.vue'
|
||||
import PaymentCreate from './views/payments/Create.vue'
|
||||
import PaymentView from './views/payments/View.vue'
|
||||
|
||||
// Estimates
|
||||
import EstimateIndex from './views/estimates/Index.vue'
|
||||
@ -259,6 +260,11 @@ const routes = [
|
||||
name: 'payments.edit',
|
||||
component: PaymentCreate
|
||||
},
|
||||
{
|
||||
path: 'payments/:id/view',
|
||||
name: 'payments.view',
|
||||
component: PaymentView
|
||||
},
|
||||
|
||||
// Expenses
|
||||
{
|
||||
|
||||
@ -4,6 +4,8 @@ import * as userTypes from './modules/user/mutation-types'
|
||||
import * as companyTypes from './modules/company/mutation-types'
|
||||
import * as preferencesTypes from './modules/settings/preferences/mutation-types'
|
||||
import * as taxTypeTypes from './modules/tax-type/mutation-types'
|
||||
import * as itemTypes from './modules/item/mutation-types'
|
||||
import * as paymentModes from './modules/payment/mutation-types'
|
||||
|
||||
export default {
|
||||
bootstrap ({ commit, dispatch, state }) {
|
||||
@ -17,6 +19,8 @@ export default {
|
||||
commit('taxType/' + taxTypeTypes.BOOTSTRAP_TAX_TYPES, response.data.taxTypes)
|
||||
commit('preferences/' + preferencesTypes.SET_MOMENT_DATE_FORMAT, response.data.moment_date_format)
|
||||
commit('preferences/' + preferencesTypes.SET_LANGUAGE_FORMAT, response.data.default_language)
|
||||
commit('item/' + itemTypes.SET_ITEM_UNITS, response.data.units)
|
||||
commit('payment/' + paymentModes.SET_PAYMENT_MODES, response.data.paymentMethods)
|
||||
commit(types.UPDATE_APP_LOADING_STATUS, true)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
|
||||
@ -135,6 +135,16 @@ export const markAsSent = ({ commit, dispatch, state }, data) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const cloneInvoice = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.post(`/api/invoices/clone`, data).then((response) => {
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const searchInvoice = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.get(`/api/invoices?${data}`).then((response) => {
|
||||
|
||||
@ -26,7 +26,6 @@ export const addItem = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.post('/api/items', data).then((response) => {
|
||||
commit(types.ADD_ITEM, response.data)
|
||||
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
@ -90,3 +89,57 @@ export const selectItem = ({ commit, dispatch, state }, data) => {
|
||||
commit(types.SET_SELECT_ALL_STATE, false)
|
||||
}
|
||||
}
|
||||
|
||||
export const addItemUnit = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.post(`/api/units`, data).then((response) => {
|
||||
commit(types.ADD_ITEM_UNIT, response.data)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const updateItemUnit = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.put(`/api/units/${data.id}`, data).then((response) => {
|
||||
commit(types.UPDATE_ITEM_UNIT, response.data)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchItemUnits = ({ commit, dispatch, state }) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.get(`/api/units`).then((response) => {
|
||||
commit(types.SET_ITEM_UNITS, response.data.units)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const fatchItemUnit = ({ commit, dispatch, state }, id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.get(`/api/units/${id}`).then((response) => {
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteItemUnit = ({ commit, dispatch, state }, id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.delete(`/api/units/${id}`).then((response) => {
|
||||
commit(types.DELETE_ITEM_UNIT, id)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -2,3 +2,4 @@ export const items = (state) => state.items
|
||||
export const selectAllField = (state) => state.selectAllField
|
||||
export const selectedItems = (state) => state.selectedItems
|
||||
export const totalItems = (state) => state.totalItems
|
||||
export const itemUnits = (state) => state.itemUnits
|
||||
|
||||
@ -6,7 +6,8 @@ const initialState = {
|
||||
items: [],
|
||||
totalItems: 0,
|
||||
selectAllField: false,
|
||||
selectedItems: []
|
||||
selectedItems: [],
|
||||
itemUnits: []
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
@ -6,3 +6,7 @@ export const DELETE_MULTIPLE_ITEMS = 'DELETE_MULTIPLE_ITEMS'
|
||||
export const SET_SELECTED_ITEMS = 'SET_SELECTED_ITEMS'
|
||||
export const SET_TOTAL_ITEMS = 'SET_TOTAL_ITEMS'
|
||||
export const SET_SELECT_ALL_STATE = 'SET_SELECT_ALL_STATE'
|
||||
export const ADD_ITEM_UNIT = 'ADD_ITEM_UNIT'
|
||||
export const SET_ITEM_UNITS = 'SET_ITEM_UNITS'
|
||||
export const UPDATE_ITEM_UNIT = 'UPDATE_ITEM_UNIT'
|
||||
export const DELETE_ITEM_UNIT = 'DELETE_ITEM_UNIT'
|
||||
|
||||
@ -39,6 +39,25 @@ export default {
|
||||
|
||||
[types.SET_SELECT_ALL_STATE] (state, data) {
|
||||
state.selectAllField = data
|
||||
}
|
||||
},
|
||||
|
||||
[types.ADD_ITEM_UNIT] (state, data) {
|
||||
state.itemUnits.push(data.unit)
|
||||
state.itemUnits = [data.unit, ...state.itemUnits]
|
||||
},
|
||||
|
||||
[types.SET_ITEM_UNITS] (state, data) {
|
||||
state.itemUnits = data
|
||||
},
|
||||
|
||||
[types.DELETE_ITEM_UNIT] (state, id) {
|
||||
let index = state.itemUnits.findIndex(unit => unit.id === id)
|
||||
state.itemUnits.splice(index, 1)
|
||||
},
|
||||
|
||||
[types.UPDATE_ITEM_UNIT] (state, data) {
|
||||
let pos = state.itemUnits.findIndex(unit => unit.id === data.unit.id)
|
||||
state.itemUnits.splice(pos, 1)
|
||||
state.itemUnits = [data.unit, ...state.itemUnits]
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,9 +12,9 @@ export const fetchPayments = ({ commit, dispatch, state }, params) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchCreatePayment = ({ commit, dispatch }, page) => {
|
||||
export const fetchPayment = ({ commit, dispatch }, id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.get(`/api/payments/create`).then((response) => {
|
||||
window.axios.get(`/api/payments/${id}`).then((response) => {
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
@ -22,7 +22,7 @@ export const fetchCreatePayment = ({ commit, dispatch }, page) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchPayment = ({ commit, dispatch }, id) => {
|
||||
export const fetchEditPaymentData = ({ commit, dispatch }, id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.get(`/api/payments/${id}/edit`).then((response) => {
|
||||
resolve(response)
|
||||
@ -32,6 +32,16 @@ export const fetchPayment = ({ commit, dispatch }, id) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchCreatePayment = ({ commit, dispatch }, page) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.get(`/api/payments/create`).then((response) => {
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const addPayment = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.post('/api/payments', data).then((response) => {
|
||||
@ -97,3 +107,78 @@ export const selectAllPayments = ({ commit, dispatch, state }) => {
|
||||
commit(types.SET_SELECT_ALL_STATE, true)
|
||||
}
|
||||
}
|
||||
|
||||
export const addPaymentMode = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.post(`/api/payment-methods`, data).then((response) => {
|
||||
commit(types.ADD_PAYMENT_MODE, response.data)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const updatePaymentMode = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.put(`/api/payment-methods/${data.id}`, data).then((response) => {
|
||||
commit(types.UPDATE_PAYMENT_MODE, response.data)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchPaymentModes = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.get(`/api/payment-methods`, data).then((response) => {
|
||||
commit(types.SET_PAYMENT_MODES, response.data.paymentMethods)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchPaymentMode = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.get(`/api/payment-methods/${data.id}`, data).then((response) => {
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const deletePaymentMode = ({ commit, dispatch, state }, id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.delete(`/api/payment-methods/${id}`).then((response) => {
|
||||
commit(types.DELETE_PAYMENT_MODE, id)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const sendEmail = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.post(`/api/payments/send`, data).then((response) => {
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const searchPayment = ({ commit, dispatch, state }, data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.axios.get(`/api/payments?${data}`).then((response) => {
|
||||
// commit(types.UPDATE_INVOICE, response.data)
|
||||
resolve(response)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -2,3 +2,4 @@ export const payments = (state) => state.payments
|
||||
export const selectedPayments = (state) => state.selectedPayments
|
||||
export const selectAllField = (state) => state.selectAllField
|
||||
export const totalPayments = (state) => state.totalPayments
|
||||
export const paymentModes = (state) => state.paymentModes
|
||||
|
||||
@ -6,7 +6,8 @@ const initialState = {
|
||||
payments: [],
|
||||
totalPayments: 0,
|
||||
selectAllField: false,
|
||||
selectedPayments: []
|
||||
selectedPayments: [],
|
||||
paymentModes: []
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
@ -6,3 +6,7 @@ export const DELETE_MULTIPLE_PAYMENTS = 'DELETE_MULTIPLE_PAYMENTS'
|
||||
export const SET_SELECTED_PAYMENTS = 'SET_SELECTED_PAYMENTS'
|
||||
export const SET_TOTAL_PAYMENTS = 'SET_TOTAL_PAYMENTS'
|
||||
export const SET_SELECT_ALL_STATE = 'SET_SELECT_ALL_STATE'
|
||||
export const ADD_PAYMENT_MODE = 'ADD_PAYMENT_MODE'
|
||||
export const DELETE_PAYMENT_MODE = 'DELETE_PAYMENT_MODE'
|
||||
export const SET_PAYMENT_MODES = 'SET_PAYMENT_MODES'
|
||||
export const UPDATE_PAYMENT_MODE = 'UPDATE_PAYMENT_MODE'
|
||||
|
||||
@ -33,5 +33,25 @@ export default {
|
||||
|
||||
[types.SET_SELECT_ALL_STATE] (state, data) {
|
||||
state.selectAllField = data
|
||||
},
|
||||
|
||||
[types.SET_PAYMENT_MODES] (state, data) {
|
||||
state.paymentModes = data
|
||||
},
|
||||
|
||||
[types.ADD_PAYMENT_MODE] (state, data) {
|
||||
state.paymentModes.push(data.paymentMethod)
|
||||
state.paymentModes = [data.paymentMethod, ...state.paymentModes]
|
||||
},
|
||||
|
||||
[types.DELETE_PAYMENT_MODE] (state, id) {
|
||||
let index = state.paymentModes.findIndex(paymentMethod => paymentMethod.id === id)
|
||||
state.paymentModes.splice(index, 1)
|
||||
},
|
||||
|
||||
[types.UPDATE_PAYMENT_MODE] (state, data) {
|
||||
let pos = state.paymentModes.findIndex(paymentMethod => paymentMethod.id === data.paymentMethod.id)
|
||||
state.paymentModes.splice(pos, 1)
|
||||
state.paymentModes = [data.paymentMethod, ...state.paymentModes]
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +85,8 @@
|
||||
</div>
|
||||
<div class="customer-content mb-1">
|
||||
<label class="email">{{ selectedCustomer.name }}</label>
|
||||
<label class="action" @click="removeCustomer">{{ $t('general.remove') }}</label>
|
||||
<label class="action" @click="editCustomer">{{ $t('general.edit') }}</label>
|
||||
<label class="action" @click="removeCustomer">{{ $t('general.deselect') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -195,6 +196,7 @@
|
||||
:index="index"
|
||||
:item-data="item"
|
||||
:currency="currency"
|
||||
:estimate-items="newEstimate.items"
|
||||
:tax-per-item="taxPerItem"
|
||||
:discount-per-item="discountPerItem"
|
||||
@remove="removeItem"
|
||||
@ -589,6 +591,14 @@ export default {
|
||||
removeCustomer () {
|
||||
this.resetSelectedCustomer()
|
||||
},
|
||||
editCustomer () {
|
||||
this.openModal({
|
||||
'title': this.$t('customers.edit_customer'),
|
||||
'componentName': 'CustomerModal',
|
||||
'id': this.selectedCustomer.id,
|
||||
'data': this.selectedCustomer
|
||||
})
|
||||
},
|
||||
openTemplateModal () {
|
||||
this.openModal({
|
||||
'title': this.$t('general.choose_template'),
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
:invalid="$v.item.name.$error"
|
||||
:invalid-description="$v.item.description.$error"
|
||||
:item="item"
|
||||
:tax-per-item="taxPerItem"
|
||||
:taxes="item.taxes"
|
||||
@search="searchVal"
|
||||
@select="onSelectItem"
|
||||
@deselect="deselectItem"
|
||||
@ -108,7 +110,7 @@
|
||||
|
||||
<div class="remove-icon-wrapper">
|
||||
<font-awesome-icon
|
||||
v-if="index > 0"
|
||||
v-if="isShowRemoveItemIcon"
|
||||
class="remove-icon"
|
||||
icon="trash-alt"
|
||||
@click="removeItem"
|
||||
@ -180,6 +182,10 @@ export default {
|
||||
discountPerItem: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
estimateItems: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
@ -221,6 +227,12 @@ export default {
|
||||
return this.defaultCurrencyForInput
|
||||
}
|
||||
},
|
||||
isShowRemoveItemIcon () {
|
||||
if (this.estimateItems.length == 1) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
subtotal () {
|
||||
return this.item.price * this.item.quantity
|
||||
},
|
||||
@ -324,6 +336,9 @@ export default {
|
||||
created () {
|
||||
window.hub.$on('checkItems', this.validateItem)
|
||||
window.hub.$on('newItem', (val) => {
|
||||
if (this.taxPerItem === 'YES') {
|
||||
this.item.taxes = val.taxes
|
||||
}
|
||||
if (!this.item.item_id && this.modalActive && this.isSelected) {
|
||||
this.onSelectItem(val)
|
||||
}
|
||||
@ -363,7 +378,13 @@ export default {
|
||||
this.item.price = item.price
|
||||
this.item.item_id = item.id
|
||||
this.item.description = item.description
|
||||
|
||||
if (this.taxPerItem === 'YES' && item.taxes) {
|
||||
let index = 0
|
||||
item.taxes.forEach(tax => {
|
||||
this.updateTax({index, item: { ...tax }})
|
||||
index++
|
||||
})
|
||||
}
|
||||
// if (this.item.taxes.length) {
|
||||
// this.item.taxes = {...item.taxes}
|
||||
// }
|
||||
|
||||
@ -68,6 +68,14 @@ export default {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
taxPerItem: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
taxes: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data () {
|
||||
@ -129,7 +137,8 @@ export default {
|
||||
this.$emit('onSelectItem')
|
||||
this.openModal({
|
||||
'title': 'Add Item',
|
||||
'componentName': 'ItemModal'
|
||||
'componentName': 'ItemModal',
|
||||
'data': {taxPerItem: this.taxPerItem, taxes: this.taxes}
|
||||
})
|
||||
},
|
||||
deselectItem () {
|
||||
|
||||
@ -69,7 +69,9 @@
|
||||
<font-awesome-icon icon="filter" />
|
||||
</base-button>
|
||||
</a>
|
||||
|
||||
<div class="filter-title">
|
||||
{{ $t('general.sort_by') }}
|
||||
</div>
|
||||
<div class="filter-items">
|
||||
<input
|
||||
id="filter_estimate_date"
|
||||
@ -107,7 +109,7 @@
|
||||
<label class="inv-label" for="filter_estimate_number">{{ $t('estimates.estimate_number') }}</label>
|
||||
</div>
|
||||
</v-dropdown>
|
||||
<base-button class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData">
|
||||
<base-button v-tooltip.top-center="{ content: getOrderName }" class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData">
|
||||
<font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" />
|
||||
<font-awesome-icon v-else icon="sort-amount-down" />
|
||||
</base-button>
|
||||
@ -172,7 +174,12 @@ export default {
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
getOrderName () {
|
||||
if (this.getOrderBy) {
|
||||
return this.$t('general.ascending')
|
||||
}
|
||||
return this.$t('general.descending')
|
||||
},
|
||||
shareableLink () {
|
||||
return `/estimates/pdf/${this.estimate.unique_hash}`
|
||||
}
|
||||
|
||||
@ -83,7 +83,8 @@
|
||||
</div>
|
||||
<div class="customer-content mb-1">
|
||||
<label class="email">{{ selectedCustomer.name }}</label>
|
||||
<label class="action" @click="removeCustomer">{{ $t('general.remove') }}</label>
|
||||
<label class="action" @click="editCustomer">{{ $t('general.edit') }}</label>
|
||||
<label class="action" @click="removeCustomer">{{ $t('general.deselect') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -193,6 +194,7 @@
|
||||
:key="item.id"
|
||||
:index="index"
|
||||
:item-data="item"
|
||||
:invoice-items="newInvoice.items"
|
||||
:currency="currency"
|
||||
:tax-per-item="taxPerItem"
|
||||
:discount-per-item="discountPerItem"
|
||||
@ -589,6 +591,14 @@ export default {
|
||||
removeCustomer () {
|
||||
this.resetSelectedCustomer()
|
||||
},
|
||||
editCustomer () {
|
||||
this.openModal({
|
||||
'title': this.$t('customers.edit_customer'),
|
||||
'componentName': 'CustomerModal',
|
||||
'id': this.selectedCustomer.id,
|
||||
'data': this.selectedCustomer
|
||||
})
|
||||
},
|
||||
openTemplateModal () {
|
||||
this.openModal({
|
||||
'title': this.$t('general.choose_template'),
|
||||
|
||||
@ -259,6 +259,18 @@
|
||||
{{ $t('invoices.mark_as_sent') }}
|
||||
</a>
|
||||
</v-dropdown-item>
|
||||
<v-dropdown-item v-if="row.status === 'SENT' || row.status === 'VIEWED' || row.status === 'OVERDUE'">
|
||||
<router-link :to="`/admin/payments/${row.id}/create`" class="dropdown-item">
|
||||
<font-awesome-icon :icon="['fas', 'credit-card']" class="dropdown-item-icon"/>
|
||||
{{ $t('payments.record_payment') }}
|
||||
</router-link>
|
||||
</v-dropdown-item>
|
||||
<v-dropdown-item>
|
||||
<a class="dropdown-item" href="#/" @click="onCloneInvoice(row.id)">
|
||||
<font-awesome-icon icon="copy" class="dropdown-item-icon" />
|
||||
{{ $t('invoices.clone_invoice') }}
|
||||
</a>
|
||||
</v-dropdown-item>
|
||||
<v-dropdown-item>
|
||||
<div class="dropdown-item" @click="removeInvoice(row.id)">
|
||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
||||
@ -378,7 +390,8 @@ export default {
|
||||
'deleteMultipleInvoices',
|
||||
'sendEmail',
|
||||
'markAsSent',
|
||||
'setSelectAllState'
|
||||
'setSelectAllState',
|
||||
'cloneInvoice'
|
||||
]),
|
||||
...mapActions('customer', [
|
||||
'fetchCustomers'
|
||||
@ -429,6 +442,27 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
async onCloneInvoice (id) {
|
||||
swal({
|
||||
title: this.$t('general.are_you_sure'),
|
||||
text: this.$t('invoices.confirm_clone'),
|
||||
icon: '/assets/icon/check-circle-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (value) => {
|
||||
if (value) {
|
||||
const data = {
|
||||
id: id
|
||||
}
|
||||
let response = await this.cloneInvoice(data)
|
||||
this.refreshTable()
|
||||
if (response.data) {
|
||||
window.toastr['success'](this.$tc('invoices.cloned_successfully'))
|
||||
this.$router.push(`/admin/invoices/${response.data.invoice.id}/edit`)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getStatus (val) {
|
||||
this.filters.status = {
|
||||
name: val,
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
:invalid="$v.item.name.$error"
|
||||
:invalid-description="$v.item.description.$error"
|
||||
:item="item"
|
||||
:tax-per-item="taxPerItem"
|
||||
:taxes="item.taxes"
|
||||
@search="searchVal"
|
||||
@select="onSelectItem"
|
||||
@deselect="deselectItem"
|
||||
@ -109,7 +111,7 @@
|
||||
|
||||
<div class="remove-icon-wrapper">
|
||||
<font-awesome-icon
|
||||
v-if="index > 0"
|
||||
v-if="showRemoveItemIcon"
|
||||
class="remove-icon"
|
||||
icon="trash-alt"
|
||||
@click="removeItem"
|
||||
@ -181,6 +183,10 @@ export default {
|
||||
discountPerItem: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
invoiceItems: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data () {
|
||||
@ -222,6 +228,12 @@ export default {
|
||||
return this.defaultCurrenctForInput
|
||||
}
|
||||
},
|
||||
showRemoveItemIcon () {
|
||||
if (this.invoiceItems.length == 1) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
subtotal () {
|
||||
return this.item.price * this.item.quantity
|
||||
},
|
||||
@ -325,6 +337,9 @@ export default {
|
||||
created () {
|
||||
window.hub.$on('checkItems', this.validateItem)
|
||||
window.hub.$on('newItem', (val) => {
|
||||
if (this.taxPerItem === 'YES') {
|
||||
this.item.taxes = val.taxes
|
||||
}
|
||||
if (!this.item.item_id && this.modalActive && this.isSelected) {
|
||||
this.onSelectItem(val)
|
||||
}
|
||||
@ -364,7 +379,13 @@ export default {
|
||||
this.item.price = item.price
|
||||
this.item.item_id = item.id
|
||||
this.item.description = item.description
|
||||
|
||||
if (this.taxPerItem === 'YES' && item.taxes) {
|
||||
let index = 0
|
||||
item.taxes.forEach(tax => {
|
||||
this.updateTax({index, item: { ...tax }})
|
||||
index++
|
||||
})
|
||||
}
|
||||
// if (this.item.taxes.length) {
|
||||
// this.item.taxes = {...item.taxes}
|
||||
// }
|
||||
|
||||
@ -66,6 +66,14 @@ export default {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
taxPerItem: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
taxes: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data () {
|
||||
@ -118,7 +126,8 @@ export default {
|
||||
this.$emit('onSelectItem')
|
||||
this.openModal({
|
||||
'title': 'Add Item',
|
||||
'componentName': 'ItemModal'
|
||||
'componentName': 'ItemModal',
|
||||
'data': {taxPerItem: this.taxPerItem, taxes: this.taxes}
|
||||
})
|
||||
},
|
||||
deselectItem () {
|
||||
|
||||
@ -73,7 +73,9 @@
|
||||
<font-awesome-icon icon="filter" />
|
||||
</base-button>
|
||||
</a>
|
||||
|
||||
<div class="filter-title">
|
||||
{{ $t('general.sort_by') }}
|
||||
</div>
|
||||
<div class="filter-items">
|
||||
<input
|
||||
id="filter_invoice_date"
|
||||
@ -111,7 +113,7 @@
|
||||
<label class="inv-label" for="filter_invoice_number">{{ $t('invoices.invoice_number') }}</label>
|
||||
</div>
|
||||
</v-dropdown>
|
||||
<base-button class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData">
|
||||
<base-button v-tooltip.top-center="{ content: getOrderName }" class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData">
|
||||
<font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" />
|
||||
<font-awesome-icon v-else icon="sort-amount-down" />
|
||||
</base-button>
|
||||
@ -168,13 +170,18 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
getOrderBy () {
|
||||
if (this.searchData.orderBy === 'asc' || this.searchData.orderBy == null) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
getOrderName () {
|
||||
if (this.getOrderBy) {
|
||||
return this.$t('general.ascending')
|
||||
}
|
||||
return this.$t('general.descending')
|
||||
},
|
||||
shareableLink () {
|
||||
return `/invoices/pdf/${this.invoice.unique_hash}`
|
||||
}
|
||||
|
||||
@ -50,11 +50,31 @@
|
||||
<label>{{ $t('items.unit') }}</label>
|
||||
<base-select
|
||||
v-model="formData.unit"
|
||||
:options="units"
|
||||
:options="itemUnits"
|
||||
:searchable="true"
|
||||
:show-labels="false"
|
||||
:placeholder="$t('items.select_a_unit')"
|
||||
label="name"
|
||||
>
|
||||
<div slot="afterList">
|
||||
<button type="button" class="list-add-button" @click="addItemUnit">
|
||||
<font-awesome-icon class="icon" icon="cart-plus" />
|
||||
<label>{{ $t('settings.customization.items.add_item_unit') }}</label>
|
||||
</button>
|
||||
</div>
|
||||
</base-select>
|
||||
</div>
|
||||
<div v-if="isTaxPerItem" class="form-group">
|
||||
<label>{{ $t('items.taxes') }}</label>
|
||||
<base-select
|
||||
v-model="formData.taxes"
|
||||
:options="getTaxTypes"
|
||||
:searchable="true"
|
||||
:show-labels="false"
|
||||
:allow-empty="true"
|
||||
:multiple="true"
|
||||
track-by="tax_type_id"
|
||||
label="tax_name"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -66,7 +86,9 @@
|
||||
@input="$v.formData.description.$touch()"
|
||||
/>
|
||||
<div v-if="$v.formData.description.$error">
|
||||
<span v-if="!$v.formData.description.maxLength" class="text-danger">{{ $t('validation.description_maxlength') }}</span>
|
||||
<span v-if="!$v.formData.description.maxLength" class="text-danger">
|
||||
{{ $t('validation.description_maxlength') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -102,24 +124,17 @@ export default {
|
||||
return {
|
||||
isLoading: false,
|
||||
title: 'Add Item',
|
||||
units: [
|
||||
{ name: 'box', value: 'box' },
|
||||
{ name: 'cm', value: 'cm' },
|
||||
{ name: 'dz', value: 'dz' },
|
||||
{ name: 'ft', value: 'ft' },
|
||||
{ name: 'g', value: 'g' },
|
||||
{ name: 'in', value: 'in' },
|
||||
{ name: 'kg', value: 'kg' },
|
||||
{ name: 'km', value: 'km' },
|
||||
{ name: 'lb', value: 'lb' },
|
||||
{ name: 'mg', value: 'mg' },
|
||||
{ name: 'pc', value: 'pc' }
|
||||
],
|
||||
units: [],
|
||||
taxes: [],
|
||||
taxPerItem: '',
|
||||
formData: {
|
||||
name: '',
|
||||
description: '',
|
||||
price: '',
|
||||
unit: null
|
||||
unit_id: null,
|
||||
unit: null,
|
||||
taxes: [],
|
||||
tax_per_item: false
|
||||
},
|
||||
money: {
|
||||
decimal: '.',
|
||||
@ -134,6 +149,9 @@ export default {
|
||||
...mapGetters('currency', [
|
||||
'defaultCurrencyForInput'
|
||||
]),
|
||||
...mapGetters('item', [
|
||||
'itemUnits'
|
||||
]),
|
||||
price: {
|
||||
get: function () {
|
||||
return this.formData.price / 100
|
||||
@ -142,14 +160,26 @@ export default {
|
||||
this.formData.price = newValue * 100
|
||||
}
|
||||
},
|
||||
...mapGetters('taxType', [
|
||||
'taxTypes'
|
||||
]),
|
||||
isEdit () {
|
||||
if (this.$route.name === 'items.edit') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
isTaxPerItem () {
|
||||
return this.taxPerItem === 'YES' ? 1 : 0
|
||||
},
|
||||
getTaxTypes () {
|
||||
return this.taxTypes.map(tax => {
|
||||
return {...tax, tax_type_id: tax.id, tax_name: tax.name + ' (' + tax.percent + '%)'}
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.setTaxPerItem()
|
||||
if (this.isEdit) {
|
||||
this.loadEditData()
|
||||
}
|
||||
@ -177,10 +207,26 @@ export default {
|
||||
'fetchItem',
|
||||
'updateItem'
|
||||
]),
|
||||
...mapActions('modal', [
|
||||
'openModal'
|
||||
]),
|
||||
async setTaxPerItem () {
|
||||
let res = await axios.get('/api/settings/get-setting?key=tax_per_item')
|
||||
if (res.data && res.data.tax_per_item === 'YES') {
|
||||
this.taxPerItem = 'YES'
|
||||
} else {
|
||||
this.taxPerItem = 'FALSE'
|
||||
}
|
||||
},
|
||||
async loadEditData () {
|
||||
let response = await this.fetchItem(this.$route.params.id)
|
||||
this.formData = response.data.item
|
||||
this.formData.unit = this.units.find(_unit => response.data.item.unit === _unit.name)
|
||||
|
||||
this.formData = {...response.data.item, unit: null}
|
||||
this.formData.taxes = response.data.item.taxes.map(tax => {
|
||||
return {...tax, tax_name: tax.name + ' (' + tax.percent + '%)'}
|
||||
})
|
||||
|
||||
this.formData.unit = this.itemUnits.find(_unit => response.data.item.unit_id === _unit.id)
|
||||
this.fractional_price = response.data.item.price
|
||||
},
|
||||
async submitItem () {
|
||||
@ -189,30 +235,40 @@ export default {
|
||||
return false
|
||||
}
|
||||
if (this.formData.unit) {
|
||||
this.formData.unit = this.formData.unit.name
|
||||
this.formData.unit_id = this.formData.unit.id
|
||||
}
|
||||
let response
|
||||
if (this.isEdit) {
|
||||
this.isLoading = true
|
||||
let response = await this.updateItem(this.formData)
|
||||
if (response.data) {
|
||||
this.isLoading = false
|
||||
window.toastr['success'](this.$tc('items.updated_message'))
|
||||
this.$router.push('/admin/items')
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
response = await this.updateItem(this.formData)
|
||||
} else {
|
||||
this.isLoading = true
|
||||
let response = await this.addItem(this.formData)
|
||||
|
||||
if (response.data) {
|
||||
window.toastr['success'](this.$tc('items.created_message'))
|
||||
this.$router.push('/admin/items')
|
||||
this.isLoading = false
|
||||
return true
|
||||
let data = {
|
||||
...this.formData,
|
||||
taxes: this.formData.taxes.map(tax => {
|
||||
return {
|
||||
tax_type_id: tax.id,
|
||||
amount: ((this.formData.price * tax.percent) / 100),
|
||||
percent: tax.percent,
|
||||
name: tax.name,
|
||||
collective_tax: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
window.toastr['success'](response.data.success)
|
||||
response = await this.addItem(data)
|
||||
}
|
||||
if (response.data) {
|
||||
this.isLoading = false
|
||||
window.toastr['success'](this.$tc('items.updated_message'))
|
||||
this.$router.push('/admin/items')
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
},
|
||||
async addItemUnit () {
|
||||
this.openModal({
|
||||
'title': 'Add Item Unit',
|
||||
'componentName': 'ItemUnit'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
<label class="form-label"> {{ $tc('items.unit') }} </label>
|
||||
<base-select
|
||||
v-model="filters.unit"
|
||||
:options="units"
|
||||
:options="itemUnits"
|
||||
:searchable="true"
|
||||
:show-labels="false"
|
||||
:placeholder="$t('items.select_a_unit')"
|
||||
@ -169,7 +169,7 @@
|
||||
/>
|
||||
<table-column
|
||||
:label="$t('items.unit')"
|
||||
show="unit"
|
||||
show="unit_name"
|
||||
/>
|
||||
<table-column
|
||||
:label="$t('items.price')"
|
||||
@ -235,19 +235,6 @@ export default {
|
||||
id: null,
|
||||
showFilters: false,
|
||||
sortedBy: 'created_at',
|
||||
units: [
|
||||
{ name: 'box', value: 'box' },
|
||||
{ name: 'cm', value: 'cm' },
|
||||
{ name: 'dz', value: 'dz' },
|
||||
{ name: 'ft', value: 'ft' },
|
||||
{ name: 'g', value: 'g' },
|
||||
{ name: 'in', value: 'in' },
|
||||
{ name: 'kg', value: 'kg' },
|
||||
{ name: 'km', value: 'km' },
|
||||
{ name: 'lb', value: 'lb' },
|
||||
{ name: 'mg', value: 'mg' },
|
||||
{ name: 'pc', value: 'pc' }
|
||||
],
|
||||
isRequestOngoing: true,
|
||||
filtersApplied: false,
|
||||
filters: {
|
||||
@ -262,7 +249,8 @@ export default {
|
||||
'items',
|
||||
'selectedItems',
|
||||
'totalItems',
|
||||
'selectAllField'
|
||||
'selectAllField',
|
||||
'itemUnits'
|
||||
]),
|
||||
...mapGetters('currency', [
|
||||
'defaultCurrency'
|
||||
@ -296,6 +284,7 @@ export default {
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
|
||||
destroyed () {
|
||||
if (this.selectAllField) {
|
||||
this.selectAllItems()
|
||||
@ -316,7 +305,7 @@ export default {
|
||||
async fetchData ({ page, filter, sort }) {
|
||||
let data = {
|
||||
search: this.filters.name !== null ? this.filters.name : '',
|
||||
unit: this.filters.unit !== null ? this.filters.unit.name : '',
|
||||
unit_id: this.filters.unit !== null ? this.filters.unit.id : '',
|
||||
price: this.filters.price * 100,
|
||||
orderByField: sort.fieldName || 'created_at',
|
||||
orderBy: sort.order || 'desc',
|
||||
@ -395,7 +384,7 @@ export default {
|
||||
}).then(async (willDelete) => {
|
||||
if (willDelete) {
|
||||
let res = await this.deleteMultipleItems()
|
||||
if (res.data.success) {
|
||||
if (res.data.success || res.data.items) {
|
||||
window.toastr['success'](this.$tc('items.deleted_message', 2))
|
||||
this.$refs.table.refresh()
|
||||
} else if (res.data.error) {
|
||||
|
||||
@ -109,12 +109,20 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ $t('payments.payment_mode') }}</label>
|
||||
<base-select
|
||||
v-model="formData.payment_mode"
|
||||
:options="getPaymentMode"
|
||||
v-model="formData.payment_method"
|
||||
:options="paymentModes"
|
||||
:searchable="true"
|
||||
:show-labels="false"
|
||||
:placeholder="$t('payments.select_payment_mode')"
|
||||
/>
|
||||
label="name"
|
||||
>
|
||||
<div slot="afterList">
|
||||
<button type="button" class="list-add-button" @click="addPaymentMode">
|
||||
<font-awesome-icon class="icon" icon="cart-plus" />
|
||||
<label>{{ $t('settings.customization.payments.add_payment_mode') }}</label>
|
||||
</button>
|
||||
</div>
|
||||
</base-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 ">
|
||||
@ -166,9 +174,10 @@ export default {
|
||||
payment_number: null,
|
||||
payment_date: null,
|
||||
amount: 0,
|
||||
payment_mode: null,
|
||||
payment_method: null,
|
||||
invoice_id: null,
|
||||
notes: null
|
||||
notes: null,
|
||||
payment_method_id: null
|
||||
},
|
||||
money: {
|
||||
decimal: '.',
|
||||
@ -215,9 +224,9 @@ export default {
|
||||
...mapGetters('currency', [
|
||||
'defaultCurrencyForInput'
|
||||
]),
|
||||
getPaymentMode () {
|
||||
return ['Cash', 'Check', 'Credit Card', 'Bank Transfer']
|
||||
},
|
||||
...mapGetters('payment', [
|
||||
'paymentModes'
|
||||
]),
|
||||
amount: {
|
||||
get: function () {
|
||||
return this.formData.amount / 100
|
||||
@ -286,14 +295,23 @@ export default {
|
||||
'fetchCreatePayment',
|
||||
'addPayment',
|
||||
'updatePayment',
|
||||
'fetchPayment'
|
||||
'fetchEditPaymentData'
|
||||
]),
|
||||
...mapActions('modal', [
|
||||
'openModal'
|
||||
]),
|
||||
invoiceWithAmount ({ invoice_number, due_amount }) {
|
||||
return `${invoice_number} (${this.$utils.formatGraphMoney(due_amount, this.customer.currency)})`
|
||||
},
|
||||
async addPaymentMode () {
|
||||
this.openModal({
|
||||
'title': 'Add Payment Mode',
|
||||
'componentName': 'PaymentMode'
|
||||
})
|
||||
},
|
||||
async loadData () {
|
||||
if (this.isEdit) {
|
||||
let response = await this.fetchPayment(this.$route.params.id)
|
||||
let response = await this.fetchEditPaymentData(this.$route.params.id)
|
||||
this.customerList = response.data.customers
|
||||
this.formData = { ...response.data.payment }
|
||||
this.customer = response.data.payment.user
|
||||
@ -301,6 +319,7 @@ export default {
|
||||
this.formData.amount = parseFloat(response.data.payment.amount)
|
||||
this.paymentPrefix = response.data.payment_prefix
|
||||
this.paymentNumAttribute = response.data.nextPaymentNumber
|
||||
this.formData.payment_method = response.data.payment.payment_method
|
||||
if (response.data.payment.invoice !== null) {
|
||||
this.maxPayableAmount = parseInt(response.data.payment.amount) + parseInt(response.data.payment.invoice.due_amount)
|
||||
this.invoice = response.data.payment.invoice
|
||||
@ -344,6 +363,7 @@ export default {
|
||||
let data = {
|
||||
editData: {
|
||||
...this.formData,
|
||||
payment_method_id: this.formData.payment_method.id,
|
||||
payment_date: moment(this.formData.payment_date).format('DD/MM/YYYY')
|
||||
},
|
||||
id: this.$route.params.id
|
||||
@ -371,6 +391,7 @@ export default {
|
||||
} else {
|
||||
let data = {
|
||||
...this.formData,
|
||||
payment_method_id: this.formData.payment_method.id,
|
||||
payment_date: moment(this.formData.payment_date).format('DD/MM/YYYY')
|
||||
}
|
||||
this.isLoading = true
|
||||
|
||||
@ -67,10 +67,11 @@
|
||||
<label class="form-label">{{ $t('payments.payment_mode') }}</label>
|
||||
<base-select
|
||||
v-model="filters.payment_mode"
|
||||
:options="payment_mode"
|
||||
:options="paymentModes"
|
||||
:searchable="true"
|
||||
:show-labels="false"
|
||||
:placeholder="$t('payments.payment_mode')"
|
||||
label="name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -203,6 +204,14 @@
|
||||
{{ $t('general.edit') }}
|
||||
</router-link>
|
||||
|
||||
</v-dropdown-item>
|
||||
<v-dropdown-item>
|
||||
|
||||
<router-link :to="{path: `payments/${row.id}/view`}" class="dropdown-item">
|
||||
<font-awesome-icon icon="eye" class="dropdown-item-icon" />
|
||||
{{ $t('general.view') }}
|
||||
</router-link>
|
||||
|
||||
</v-dropdown-item>
|
||||
<v-dropdown-item>
|
||||
<div class="dropdown-item" @click="removePayment(row.id)">
|
||||
@ -237,7 +246,6 @@ export default {
|
||||
sortedBy: 'created_at',
|
||||
filtersApplied: false,
|
||||
isRequestOngoing: true,
|
||||
payment_mode: ['Cash', 'Check', 'Credit Card', 'Bank Transfer'],
|
||||
filters: {
|
||||
customer: null,
|
||||
payment_mode: '',
|
||||
@ -259,7 +267,8 @@ export default {
|
||||
'selectedPayments',
|
||||
'totalPayments',
|
||||
'payments',
|
||||
'selectAllField'
|
||||
'selectAllField',
|
||||
'paymentModes'
|
||||
]),
|
||||
selectField: {
|
||||
get: function () {
|
||||
@ -308,7 +317,7 @@ export default {
|
||||
let data = {
|
||||
customer_id: this.filters.customer !== null ? this.filters.customer.id : '',
|
||||
payment_number: this.filters.payment_number,
|
||||
payment_mode: this.filters.payment_mode ? this.filters.payment_mode : '',
|
||||
payment_method_id: this.filters.payment_mode ? this.filters.payment_mode.id : '',
|
||||
orderByField: sort.fieldName || 'created_at',
|
||||
orderBy: sort.order || 'desc',
|
||||
page
|
||||
|
||||
286
resources/assets/js/views/payments/View.vue
Normal file
286
resources/assets/js/views/payments/View.vue
Normal file
@ -0,0 +1,286 @@
|
||||
<template>
|
||||
<div v-if="payment" class="main-content payment-view-page">
|
||||
<div class="page-header">
|
||||
<h3 class="page-title"> {{ payment.payment_number }}</h3>
|
||||
<div class="page-actions row">
|
||||
<base-button
|
||||
:loading="isSendingEmail"
|
||||
:disabled="isSendingEmail"
|
||||
:outline="true"
|
||||
color="theme"
|
||||
@click="onPaymentSend"
|
||||
>
|
||||
{{ $t('payments.send_payment_receipt') }}
|
||||
</base-button>
|
||||
<v-dropdown :close-on-select="false" align="left" class="filter-container">
|
||||
<a slot="activator" href="#">
|
||||
<base-button color="theme">
|
||||
<font-awesome-icon icon="ellipsis-h" />
|
||||
</base-button>
|
||||
</a>
|
||||
<v-dropdown-item>
|
||||
<router-link :to="{path: `/admin/payments/${$route.params.id}/edit`}" class="dropdown-item">
|
||||
<font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon"/>
|
||||
{{ $t('general.edit') }}
|
||||
</router-link>
|
||||
<div class="dropdown-item" @click="removePayment($route.params.id)">
|
||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
||||
{{ $t('general.delete') }}
|
||||
</div>
|
||||
</v-dropdown-item>
|
||||
</v-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="payment-sidebar">
|
||||
<div class="side-header">
|
||||
<base-input
|
||||
v-model="searchData.searchText"
|
||||
:placeholder="$t('general.search')"
|
||||
input-class="inv-search"
|
||||
icon="search"
|
||||
type="text"
|
||||
align-icon="right"
|
||||
@input="onSearch"
|
||||
/>
|
||||
<div
|
||||
class="btn-group ml-3"
|
||||
role="group"
|
||||
aria-label="First group"
|
||||
>
|
||||
<v-dropdown :close-on-select="false" align="left" class="filter-container">
|
||||
<a slot="activator" href="#">
|
||||
<base-button class="inv-button inv-filter-fields-btn" color="default" size="medium">
|
||||
<font-awesome-icon icon="filter" />
|
||||
</base-button>
|
||||
</a>
|
||||
<div class="filter-title">
|
||||
{{ $t('general.sort_by') }}
|
||||
</div>
|
||||
<div class="filter-items">
|
||||
<input
|
||||
id="filter_invoice_number"
|
||||
v-model="searchData.orderByField"
|
||||
type="radio"
|
||||
name="filter"
|
||||
class="inv-radio"
|
||||
value="invoice_number"
|
||||
@change="onSearch"
|
||||
>
|
||||
<label class="inv-label" for="filter_invoice_number">{{ $t('invoices.title') }}</label>
|
||||
</div>
|
||||
<div class="filter-items">
|
||||
<input
|
||||
id="filter_payment_date"
|
||||
v-model="searchData.orderByField"
|
||||
type="radio"
|
||||
name="filter"
|
||||
class="inv-radio"
|
||||
value="payment_date"
|
||||
@change="onSearch"
|
||||
>
|
||||
<label class="inv-label" for="filter_payment_date">{{ $t('payments.date') }}</label>
|
||||
</div>
|
||||
<div class="filter-items">
|
||||
<input
|
||||
id="filter_payment_number"
|
||||
v-model="searchData.orderByField"
|
||||
type="radio"
|
||||
name="filter"
|
||||
class="inv-radio"
|
||||
value="payment_number"
|
||||
@change="onSearch"
|
||||
>
|
||||
<label class="inv-label" for="filter_payment_number">{{ $t('payments.payment_number') }}</label>
|
||||
</div>
|
||||
</v-dropdown>
|
||||
<base-button v-tooltip.top-center="{ content: getOrderName }" class="inv-button inv-filter-sorting-btn" color="default" size="medium" @click="sortData">
|
||||
<font-awesome-icon v-if="getOrderBy" icon="sort-amount-up" />
|
||||
<font-awesome-icon v-else icon="sort-amount-down" />
|
||||
</base-button>
|
||||
</div>
|
||||
</div>
|
||||
<base-loader v-if="isSearching" />
|
||||
<div v-else class="side-content">
|
||||
<router-link
|
||||
v-for="(payment,index) in payments"
|
||||
:to="`/admin/payments/${payment.id}/view`"
|
||||
:key="index"
|
||||
class="side-payment"
|
||||
>
|
||||
<div class="left">
|
||||
<div class="inv-name">{{ payment.user.name }}</div>
|
||||
<div class="inv-number">{{ payment.payment_number }}</div>
|
||||
<div class="inv-number">{{ payment.invoice_number }}</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="inv-amount" v-html="$utils.formatMoney(payment.amount, payment.user.currency)" />
|
||||
<div class="inv-date">{{ payment.formattedPaymentDate }}</div>
|
||||
<!-- <div class="inv-number">{{ payment.payment_method.name }}</div> -->
|
||||
</div>
|
||||
</router-link>
|
||||
<p v-if="!payments.length" class="no-result">
|
||||
{{ $t('payments.no_matching_invoices') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="payment-view-page-container" >
|
||||
<iframe :src="`${shareableLink}`" class="frame-style"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
const _ = require('lodash')
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
id: null,
|
||||
count: null,
|
||||
payments: [],
|
||||
payment: null,
|
||||
currency: null,
|
||||
searchData: {
|
||||
orderBy: null,
|
||||
orderByField: null,
|
||||
searchText: null
|
||||
},
|
||||
isRequestOnGoing: false,
|
||||
isSearching: false,
|
||||
isSendingEmail: false,
|
||||
isMarkingAsSent: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getOrderBy () {
|
||||
if (this.searchData.orderBy === 'asc' || this.searchData.orderBy == null) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
getOrderName () {
|
||||
if (this.getOrderBy) {
|
||||
return this.$t('general.ascending')
|
||||
}
|
||||
return this.$t('general.descending')
|
||||
},
|
||||
shareableLink () {
|
||||
return `/payments/pdf/${this.payment.unique_hash}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route (to, from) {
|
||||
this.loadPayment()
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.loadPayments()
|
||||
this.loadPayment()
|
||||
this.onSearch = _.debounce(this.onSearch, 500)
|
||||
},
|
||||
methods: {
|
||||
// ...mapActions('invoice', [
|
||||
// 'fetchInvoices',
|
||||
// 'getRecord',
|
||||
// 'searchInvoice',
|
||||
// 'markAsSent',
|
||||
// 'sendEmail',
|
||||
// 'deleteInvoice',
|
||||
// 'fetchViewInvoice'
|
||||
// ]),
|
||||
...mapActions('payment', [
|
||||
'fetchPayments',
|
||||
'fetchPayment',
|
||||
'sendEmail',
|
||||
'deletePayment',
|
||||
'searchPayment'
|
||||
]),
|
||||
async loadPayments () {
|
||||
let response = await this.fetchPayments()
|
||||
if (response.data) {
|
||||
this.payments = response.data.payments.data
|
||||
}
|
||||
},
|
||||
async loadPayment () {
|
||||
let response = await this.fetchPayment(this.$route.params.id)
|
||||
|
||||
if (response.data) {
|
||||
this.payment = response.data.payment
|
||||
}
|
||||
},
|
||||
async onSearch () {
|
||||
let data = ''
|
||||
if (this.searchData.searchText !== '' && this.searchData.searchText !== null && this.searchData.searchText !== undefined) {
|
||||
data += `search=${this.searchData.searchText}&`
|
||||
}
|
||||
|
||||
if (this.searchData.orderBy !== null && this.searchData.orderBy !== undefined) {
|
||||
data += `orderBy=${this.searchData.orderBy}&`
|
||||
}
|
||||
|
||||
if (this.searchData.orderByField !== null && this.searchData.orderByField !== undefined) {
|
||||
data += `orderByField=${this.searchData.orderByField}`
|
||||
}
|
||||
this.isSearching = true
|
||||
let response = await this.searchPayment(data)
|
||||
this.isSearching = false
|
||||
if (response.data) {
|
||||
this.payments = response.data.payments.data
|
||||
}
|
||||
},
|
||||
sortData () {
|
||||
if (this.searchData.orderBy === 'asc') {
|
||||
this.searchData.orderBy = 'desc'
|
||||
this.onSearch()
|
||||
return true
|
||||
}
|
||||
this.searchData.orderBy = 'asc'
|
||||
this.onSearch()
|
||||
return true
|
||||
},
|
||||
async onPaymentSend () {
|
||||
window.swal({
|
||||
title: this.$tc('general.are_you_sure'),
|
||||
text: this.$tc('payments.confirm_send_payment'),
|
||||
icon: '/assets/icon/paper-plane-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (value) => {
|
||||
if (value) {
|
||||
this.isSendingEmail = true
|
||||
let response = await this.sendEmail({id: this.payment.id})
|
||||
this.isSendingEmail = false
|
||||
if (response.data.success) {
|
||||
window.toastr['success'](this.$tc('payments.send_payment_successfully'))
|
||||
return true
|
||||
}
|
||||
if (response.data.error === 'user_email_does_not_exist') {
|
||||
window.toastr['error'](this.$tc('payments.user_email_does_not_exist'))
|
||||
return false
|
||||
}
|
||||
window.toastr['error'](this.$tc('payments.something_went_wrong'))
|
||||
}
|
||||
})
|
||||
},
|
||||
async removePayment (id) {
|
||||
this.id = id
|
||||
window.swal({
|
||||
title: 'Deleted',
|
||||
text: 'you will not be able to recover this payment!',
|
||||
icon: '/assets/icon/trash-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (value) => {
|
||||
if (value) {
|
||||
let request = await this.deletePayment(this.id)
|
||||
if (request.data.success) {
|
||||
window.toastr['success'](this.$tc('payments.deleted_message', 1))
|
||||
this.$router.push('/admin/payments')
|
||||
} else if (request.data.error) {
|
||||
window.toastr['error'](request.data.message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -11,12 +11,15 @@
|
||||
<li class="tab" @click="setActiveTab('PAYMENTS')">
|
||||
<a :class="['tab-link', {'a-active': activeTab === 'PAYMENTS'}]" href="#">{{ $t('settings.customization.payments.title') }}</a>
|
||||
</li>
|
||||
<li class="tab" @click="setActiveTab('ITEMS')">
|
||||
<a :class="['tab-link', {'a-active': activeTab === 'ITEMS'}]" href="#">{{ $t('settings.customization.items.title') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Invoices Tab -->
|
||||
<transition name="fade-customize">
|
||||
<div v-if="activeTab === 'INVOICES'" class="invoice-tab">
|
||||
<form action="" class="form-section" @submit.prevent="updateInvoiceSetting">
|
||||
<form action="" class="mt-3" @submit.prevent="updateInvoiceSetting">
|
||||
<div class="row">
|
||||
<div class="col-md-12 mb-4">
|
||||
<label class="input-label">{{ $t('settings.customization.invoices.invoice_prefix') }}</label>
|
||||
@ -32,7 +35,7 @@
|
||||
<span v-if="!$v.invoices.invoice_prefix.alpha" class="text-danger">{{ $t('validation.characters_only') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="row pb-3">
|
||||
<div class="col-md-12">
|
||||
<base-button
|
||||
icon="save"
|
||||
@ -43,25 +46,23 @@
|
||||
</base-button>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
</form>
|
||||
<div class="col-md-12 mt-3">
|
||||
<div class="page-header">
|
||||
<h3 class="page-title">
|
||||
{{ $t('settings.customization.invoices.invoice_settings') }}
|
||||
</h3>
|
||||
<div class="flex-box">
|
||||
<div class="left">
|
||||
<base-switch
|
||||
v-model="invoiceAutogenerate"
|
||||
class="btn-switch"
|
||||
@change="setInvoiceSetting"
|
||||
/>
|
||||
</div>
|
||||
<div class="right ml-15">
|
||||
<p class="box-title"> {{ $t('settings.customization.invoices.autogenerate_invoice_number') }} </p>
|
||||
<p class="box-desc"> {{ $t('settings.customization.invoices.invoice_setting_description') }} </p>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="page-header pt-3">
|
||||
<h3 class="page-title">
|
||||
{{ $t('settings.customization.invoices.invoice_settings') }}
|
||||
</h3>
|
||||
<div class="flex-box">
|
||||
<div class="left">
|
||||
<base-switch
|
||||
v-model="invoiceAutogenerate"
|
||||
class="btn-switch"
|
||||
@change="setInvoiceSetting"
|
||||
/>
|
||||
</div>
|
||||
<div class="right ml-15">
|
||||
<p class="box-title"> {{ $t('settings.customization.invoices.autogenerate_invoice_number') }} </p>
|
||||
<p class="box-desc"> {{ $t('settings.customization.invoices.invoice_setting_description') }} </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -71,7 +72,7 @@
|
||||
<!-- Estimates Tab -->
|
||||
<transition name="fade-customize">
|
||||
<div v-if="activeTab === 'ESTIMATES'" class="estimate-tab">
|
||||
<form action="" class="form-section" @submit.prevent="updateEstimateSetting">
|
||||
<form action="" class="mt-3" @submit.prevent="updateEstimateSetting">
|
||||
<div class="row">
|
||||
<div class="col-md-12 mb-4">
|
||||
<label class="input-label">{{ $t('settings.customization.estimates.estimate_prefix') }}</label>
|
||||
@ -87,7 +88,7 @@
|
||||
<span v-if="!$v.estimates.estimate_prefix.alpha" class="text-danger">{{ $t('validation.characters_only') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="row pb-3">
|
||||
<div class="col-md-12">
|
||||
<base-button
|
||||
icon="save"
|
||||
@ -100,23 +101,21 @@
|
||||
</div>
|
||||
<hr>
|
||||
</form>
|
||||
<div class="col-md-12 mt-3">
|
||||
<div class="page-header">
|
||||
<h3 class="page-title">
|
||||
{{ $t('settings.customization.estimates.estimate_settings') }}
|
||||
</h3>
|
||||
<div class="flex-box">
|
||||
<div class="left">
|
||||
<base-switch
|
||||
v-model="estimateAutogenerate"
|
||||
class="btn-switch"
|
||||
@change="setEstimateSetting"
|
||||
/>
|
||||
</div>
|
||||
<div class="right ml-15">
|
||||
<p class="box-title"> {{ $t('settings.customization.estimates.autogenerate_estimate_number') }} </p>
|
||||
<p class="box-desc"> {{ $t('settings.customization.estimates.estimate_setting_description') }} </p>
|
||||
</div>
|
||||
<div class="page-header pt-3">
|
||||
<h3 class="page-title">
|
||||
{{ $t('settings.customization.estimates.estimate_settings') }}
|
||||
</h3>
|
||||
<div class="flex-box">
|
||||
<div class="left">
|
||||
<base-switch
|
||||
v-model="estimateAutogenerate"
|
||||
class="btn-switch"
|
||||
@change="setEstimateSetting"
|
||||
/>
|
||||
</div>
|
||||
<div class="right ml-15">
|
||||
<p class="box-title"> {{ $t('settings.customization.estimates.autogenerate_estimate_number') }} </p>
|
||||
<p class="box-desc"> {{ $t('settings.customization.estimates.estimate_setting_description') }} </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -126,7 +125,66 @@
|
||||
<!-- Payments Tab -->
|
||||
<transition name="fade-customize">
|
||||
<div v-if="activeTab === 'PAYMENTS'" class="payment-tab">
|
||||
<form action="" class="form-section" @submit.prevent="updatePaymentSetting">
|
||||
<div class="page-header">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<!-- <h3 class="page-title">
|
||||
{{ $t('settings.customization.payments.payment_mode') }}
|
||||
</h3> -->
|
||||
</div>
|
||||
<div class="col-md-4 d-flex flex-row-reverse">
|
||||
<base-button
|
||||
outline
|
||||
class="add-new-tax"
|
||||
color="theme"
|
||||
@click="addPaymentMode"
|
||||
>
|
||||
{{ $t('settings.customization.payments.add_payment_mode') }}
|
||||
</base-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table-component
|
||||
ref="table"
|
||||
:show-filter="false"
|
||||
:data="paymentModes"
|
||||
table-class="table tax-table"
|
||||
class="mb-3"
|
||||
>
|
||||
<table-column
|
||||
:sortable="true"
|
||||
:label="$t('settings.customization.payments.payment_mode')"
|
||||
show="name"
|
||||
/>
|
||||
<table-column
|
||||
:sortable="false"
|
||||
:filterable="false"
|
||||
cell-class="action-dropdown"
|
||||
>
|
||||
<template slot-scope="row">
|
||||
<span>{{ $t('settings.tax_types.action') }}</span>
|
||||
<v-dropdown>
|
||||
<a slot="activator" href="#">
|
||||
<dot-icon />
|
||||
</a>
|
||||
<v-dropdown-item>
|
||||
<div class="dropdown-item" @click="editPaymentMode(row)">
|
||||
<font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon" />
|
||||
{{ $t('general.edit') }}
|
||||
</div>
|
||||
</v-dropdown-item>
|
||||
<v-dropdown-item>
|
||||
<div class="dropdown-item" @click="removePaymentMode(row.id)">
|
||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
||||
{{ $t('general.delete') }}
|
||||
</div>
|
||||
</v-dropdown-item>
|
||||
</v-dropdown>
|
||||
</template>
|
||||
</table-column>
|
||||
</table-component>
|
||||
<hr>
|
||||
<form action="" class="pt-3" @submit.prevent="updatePaymentSetting">
|
||||
<div class="row">
|
||||
<div class="col-md-12 mb-4">
|
||||
<label class="input-label">{{ $t('settings.customization.payments.payment_prefix') }}</label>
|
||||
@ -142,7 +200,7 @@
|
||||
<span v-if="!$v.payments.payment_prefix.alpha" class="text-danger">{{ $t('validation.characters_only') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="row pb-3">
|
||||
<div class="col-md-12">
|
||||
<base-button
|
||||
icon="save"
|
||||
@ -155,33 +213,97 @@
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
<div class="col-md-12 mt-4">
|
||||
<div class="page-header">
|
||||
<h3 class="page-title">
|
||||
{{ $t('settings.customization.payments.payment_settings') }}
|
||||
</h3>
|
||||
<div class="flex-box">
|
||||
<div class="left">
|
||||
<base-switch
|
||||
v-model="paymentAutogenerate"
|
||||
class="btn-switch"
|
||||
@change="setPaymentSetting"
|
||||
/>
|
||||
</div>
|
||||
<div class="right ml-15">
|
||||
<p class="box-title"> {{ $t('settings.customization.payments.autogenerate_payment_number') }} </p>
|
||||
<p class="box-desc"> {{ $t('settings.customization.payments.payment_setting_description') }} </p>
|
||||
</div>
|
||||
<div class="page-header pt-3">
|
||||
<h3 class="page-title">
|
||||
{{ $t('settings.customization.payments.payment_settings') }}
|
||||
</h3>
|
||||
<div class="flex-box">
|
||||
<div class="left">
|
||||
<base-switch
|
||||
v-model="paymentAutogenerate"
|
||||
class="btn-switch"
|
||||
@change="setPaymentSetting"
|
||||
/>
|
||||
</div>
|
||||
<div class="right ml-15">
|
||||
<p class="box-title"> {{ $t('settings.customization.payments.autogenerate_payment_number') }} </p>
|
||||
<p class="box-desc"> {{ $t('settings.customization.payments.payment_setting_description') }} </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- Items Tab -->
|
||||
<transition name="fade-customize">
|
||||
<div v-if="activeTab === 'ITEMS'" class="item-tab">
|
||||
<div class="page-header">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<!-- <h3 class="page-title">
|
||||
{{ $t('settings.customization.items.title') }}
|
||||
</h3> -->
|
||||
</div>
|
||||
<div class="col-md-4 d-flex flex-row-reverse">
|
||||
<base-button
|
||||
outline
|
||||
class="add-new-tax"
|
||||
color="theme"
|
||||
@click="addItemUnit"
|
||||
>
|
||||
{{ $t('settings.customization.items.add_item_unit') }}
|
||||
</base-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table-component
|
||||
ref="itemTable"
|
||||
:show-filter="false"
|
||||
:data="itemUnits"
|
||||
table-class="table tax-table"
|
||||
class="mb-3"
|
||||
>
|
||||
<table-column
|
||||
:sortable="true"
|
||||
:label="$t('settings.customization.items.units')"
|
||||
show="name"
|
||||
/>
|
||||
<table-column
|
||||
:sortable="false"
|
||||
:filterable="false"
|
||||
cell-class="action-dropdown"
|
||||
>
|
||||
<template slot-scope="row">
|
||||
<span>{{ $t('settings.tax_types.action') }}</span>
|
||||
<v-dropdown>
|
||||
<a slot="activator" href="#">
|
||||
<dot-icon />
|
||||
</a>
|
||||
<v-dropdown-item>
|
||||
<div class="dropdown-item" @click="editItemUnit(row)">
|
||||
<font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon" />
|
||||
{{ $t('general.edit') }}
|
||||
</div>
|
||||
</v-dropdown-item>
|
||||
<v-dropdown-item>
|
||||
<div class="dropdown-item" @click="removeItemUnit(row.id)">
|
||||
<font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" />
|
||||
{{ $t('general.delete') }}
|
||||
</div>
|
||||
</v-dropdown-item>
|
||||
</v-dropdown>
|
||||
</template>
|
||||
</table-column>
|
||||
</table-component>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { validationMixin } from 'vuelidate'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
const { required, maxLength, alpha } = require('vuelidate/lib/validators')
|
||||
export default {
|
||||
mixins: [validationMixin],
|
||||
@ -204,9 +326,20 @@ export default {
|
||||
payments: {
|
||||
payment_prefix: null
|
||||
},
|
||||
items: {
|
||||
units: []
|
||||
},
|
||||
currentData: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('item', [
|
||||
'itemUnits'
|
||||
]),
|
||||
...mapGetters('payment', [
|
||||
'paymentModes'
|
||||
])
|
||||
},
|
||||
watch: {
|
||||
activeTab () {
|
||||
this.loadData()
|
||||
@ -239,6 +372,15 @@ export default {
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
...mapActions('modal', [
|
||||
'openModal'
|
||||
]),
|
||||
...mapActions('payment', [
|
||||
'deletePaymentMode'
|
||||
]),
|
||||
...mapActions('item', [
|
||||
'deleteItemUnit'
|
||||
]),
|
||||
async setInvoiceSetting () {
|
||||
let data = {
|
||||
key: 'invoice_auto_generate',
|
||||
@ -259,6 +401,78 @@ export default {
|
||||
window.toastr['success'](this.$t('general.setting_updated'))
|
||||
}
|
||||
},
|
||||
async addItemUnit () {
|
||||
this.openModal({
|
||||
'title': 'Add Item Unit',
|
||||
'componentName': 'ItemUnit'
|
||||
})
|
||||
this.$refs.itemTable.refresh()
|
||||
},
|
||||
async editItemUnit (data) {
|
||||
this.openModal({
|
||||
'title': 'Edit Item Unit',
|
||||
'componentName': 'ItemUnit',
|
||||
'id': data.id,
|
||||
'data': data
|
||||
})
|
||||
this.$refs.itemTable.refresh()
|
||||
},
|
||||
async removeItemUnit (id) {
|
||||
swal({
|
||||
title: this.$t('general.are_you_sure'),
|
||||
text: this.$t('settings.customization.items.item_unit_confirm_delete'),
|
||||
icon: '/assets/icon/trash-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (value) => {
|
||||
if (value) {
|
||||
let response = await this.deleteItemUnit(id)
|
||||
if (response.data.success) {
|
||||
window.toastr['success'](this.$t('settings.customization.items.deleted_message'))
|
||||
this.id = null
|
||||
this.$refs.itemTable.refresh()
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](this.$t('settings.customization.items.already_in_use'))
|
||||
}
|
||||
})
|
||||
},
|
||||
async addPaymentMode () {
|
||||
this.openModal({
|
||||
'title': 'Add Payment Mode',
|
||||
'componentName': 'PaymentMode'
|
||||
})
|
||||
this.$refs.table.refresh()
|
||||
},
|
||||
async editPaymentMode (data) {
|
||||
this.openModal({
|
||||
'title': 'Edit Payment Mode',
|
||||
'componentName': 'PaymentMode',
|
||||
'id': data.id,
|
||||
'data': data
|
||||
})
|
||||
this.$refs.table.refresh()
|
||||
},
|
||||
removePaymentMode (id) {
|
||||
swal({
|
||||
title: this.$t('general.are_you_sure'),
|
||||
text: this.$t('settings.customization.payments.payment_mode_confirm_delete'),
|
||||
icon: '/assets/icon/trash-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (value) => {
|
||||
if (value) {
|
||||
let response = await this.deletePaymentMode(id)
|
||||
if (response.data.success) {
|
||||
window.toastr['success'](this.$t('settings.customization.payments.deleted_message'))
|
||||
this.id = null
|
||||
this.$refs.table.refresh()
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](this.$t('settings.customization.payments.already_in_use'))
|
||||
}
|
||||
})
|
||||
},
|
||||
changeToUppercase (currentTab) {
|
||||
if (currentTab === 'INVOICES') {
|
||||
this.invoices.invoice_prefix = this.invoices.invoice_prefix.toUpperCase()
|
||||
|
||||
@ -15,7 +15,19 @@
|
||||
:mail-drivers="mail_drivers"
|
||||
@on-change-driver="(val) => mail_driver = mailConfigData.mail_driver = val"
|
||||
@submit-data="saveEmailConfig"
|
||||
/>
|
||||
>
|
||||
<base-button
|
||||
:loading="loading"
|
||||
outline
|
||||
class="pull-right mt-4 ml-2"
|
||||
icon="check"
|
||||
color="theme"
|
||||
type="button"
|
||||
@click="openMailTestModal"
|
||||
>
|
||||
{{ $t('general.test_mail_conf') }}
|
||||
</base-button>
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -27,6 +39,7 @@ import Smtp from './mailDriver/Smtp'
|
||||
import Mailgun from './mailDriver/Mailgun'
|
||||
import Ses from './mailDriver/Ses'
|
||||
import Basic from './mailDriver/Basic'
|
||||
import { mapActions } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -50,6 +63,9 @@ export default {
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
...mapActions('modal', [
|
||||
'openModal'
|
||||
]),
|
||||
async loadData () {
|
||||
this.loading = true
|
||||
|
||||
@ -79,6 +95,12 @@ export default {
|
||||
} catch (e) {
|
||||
window.toastr['error']('Something went wrong')
|
||||
}
|
||||
},
|
||||
openMailTestModal () {
|
||||
this.openModal({
|
||||
'title': 'Test Mail Configuration',
|
||||
'componentName': 'MailTestModal'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,15 +73,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<base-button
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
icon="save"
|
||||
color="theme"
|
||||
type="submit"
|
||||
>
|
||||
{{ $t('general.save') }}
|
||||
</base-button>
|
||||
<div class="d-flex">
|
||||
<base-button
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
icon="save"
|
||||
color="theme"
|
||||
type="submit"
|
||||
>
|
||||
{{ $t('general.save') }}
|
||||
</base-button>
|
||||
<slot/>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@ -167,15 +167,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<base-button
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
icon="save"
|
||||
color="theme"
|
||||
type="submit"
|
||||
>
|
||||
{{ $t('general.save') }}
|
||||
</base-button>
|
||||
<div class="d-flex">
|
||||
<base-button
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
icon="save"
|
||||
color="theme"
|
||||
type="submit"
|
||||
>
|
||||
{{ $t('general.save') }}
|
||||
</base-button>
|
||||
<slot/>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@ -146,15 +146,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<base-button
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
icon="save"
|
||||
color="theme"
|
||||
type="submit"
|
||||
>
|
||||
{{ $t('general.save') }}
|
||||
</base-button>
|
||||
<div class="d-flex">
|
||||
<base-button
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
icon="save"
|
||||
color="theme"
|
||||
type="submit"
|
||||
>
|
||||
{{ $t('general.save') }}
|
||||
</base-button>
|
||||
<slot/>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@ -146,15 +146,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<base-button
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
icon="save"
|
||||
color="theme"
|
||||
type="submit"
|
||||
>
|
||||
{{ $t('general.save') }}
|
||||
</base-button>
|
||||
<div class="d-flex">
|
||||
<base-button
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
icon="save"
|
||||
color="theme"
|
||||
type="submit"
|
||||
>
|
||||
{{ $t('general.save') }}
|
||||
</base-button>
|
||||
<slot/>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@ -54,7 +54,6 @@
|
||||
:placeholder="$t('general.select_country')"
|
||||
track-by="id"
|
||||
label="name"
|
||||
@input="fetchState()"
|
||||
/>
|
||||
<div v-if="$v.companyData.country_id.$error">
|
||||
<span v-if="!$v.companyData.country_id.required" class="text-danger">{{ $tc('validation.required') }}</span>
|
||||
|
||||
Reference in New Issue
Block a user