fix conflicts

This commit is contained in:
yogesh_gohil
2019-11-14 15:51:48 +05:30
parent 4839e57791
commit 2dda0baa3f
51 changed files with 576 additions and 226 deletions

View File

@ -228,6 +228,10 @@ export default {
save_estimate: 'Save Estimate',
confirm_conversion: 'You want to convert this Estimate into Invoice?',
conversion_message: 'Conversion 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',
confirm_mark_as_accepted: 'This estimate will be marked as Accepted',
confirm_mark_as_rejected: 'This estimate will be marked as Rejected',
no_matching_estimates: 'There are no matching estimates!',
errors: {
required: 'Field is required'
@ -303,7 +307,9 @@ export default {
send_invoice: 'Send Invoice',
invoice_template: 'Invoice Template',
template: 'Template',
mark_as_sent: 'Mark as Sent',
mark_as_sent: 'Mark as sent',
invoice_mark_as_sent: 'This invoice will be marked as sent',
confirm_send: 'This invoice will be sent via email to the customer',
invoice_date: 'Invoice Date',
record_payment: 'Record Payment',
add_new_invoice: 'Add New Invoice',
@ -522,7 +528,8 @@ export default {
preferences: 'Preferences',
notifications: 'Notifications',
tax_types: 'Tax Types',
expense_category: 'Expense Categories'
expense_category: 'Expense Categories',
update_app: 'Update App'
},
title: 'Settings',
setting: 'Settings | Settings',
@ -624,6 +631,7 @@ export default {
created_message: 'Sales tax created successfully',
updated_message: 'Sales tax updated successfully',
deleted_message: 'Sales tax deleted successfully',
confirm_delete: 'You will not be able to recover this Tax Type',
already_in_use: 'Tax is already in use'
},
expense_category: {
@ -636,6 +644,7 @@ export default {
created_message: 'Category created successfully',
deleted_message: 'Expense category deleted successfully',
updated_message: 'Expense category updated successfully',
confirm_delete: 'You will not be able to recover this Expense Category',
already_in_use: 'Category is already in use'
},
preferences: {
@ -656,6 +665,11 @@ export default {
select_time_zone: 'select Time Zone',
select_date_formate: 'select Date Formate',
select_financial_year: 'select financial year'
},
update_app: {
title: 'Update App',
description: 'update app description',
update: 'Update'
}
},
wizard: {
@ -745,6 +759,7 @@ export default {
invalid_url: 'Invalid url (ex: http://www.crater.com)',
required: 'Field is required',
email_incorrect: 'Incorrect Email.',
email_already_taken: 'The email has already been taken.',
email_does_not_exist: "User with given email doesn't exist",
send_reset_link: 'Send Reset Link',
not_yet: 'Not yet? Send it again',
@ -761,9 +776,9 @@ export default {
payment_greater_than_due_amount: 'Entered Payment is more than due amount of this invoice.',
quantity_maxlength: 'Quantity should not be greater than 10 digits.',
price_maxlength: 'Price should not be greater than 10 digits.',
price_minvalue: 'Price should be greater than 0 digits',
price_minvalue: 'Price should be greater than 0.',
amount_maxlength: 'Amount should not be greater than 10 digits.',
amount_minvalue: 'Amount should be greater than 0 digits',
amount_minvalue: 'Amount should be greater than 0.',
description_maxlength: 'Description 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.',

View File

@ -228,12 +228,15 @@ export default {
estimate_template: 'Plantilla de estimación',
convert_to_invoice: 'Convertir a factura',
mark_as_sent: 'Marcar como enviado',
send_estimate: 'Enviar presupuesto',
record_payment: 'Registro de pago',
add_estimate: 'Agregar presupuesto',
save_estimate: 'Guardar estimación',
confirm_conversion: '¿Quiere convertir esta estimación en factura?',
conversion_message: 'Conversión exitosa',
confirm_send_estimate: 'Esta estimación se enviará por correo electrónico al cliente',
confirm_mark_as_sent: 'Esta estimación se marcará como enviada',
confirm_mark_as_accepted: 'Esta estimación se marcará como Aceptada',
confirm_mark_as_rejected: 'Esta estimación se marcará como Rechazada',
errors: {
required: 'Se requiere campo'
},
@ -309,6 +312,8 @@ export default {
invoice_template: 'Plantilla de factura',
template: 'Modelo',
mark_as_sent: 'Marcar como enviado',
invoice_mark_as_sent: 'Esta factura se marcará como enviada',
confirm_send: 'Estas facturas se enviarán por correo electrónico al cliente.',
invoice_date: 'Fecha de la factura',
record_payment: 'Registro de pago',
add_new_invoice: 'Añadir nueva factura',
@ -551,6 +556,16 @@ export default {
action: 'Acción',
add_currency: 'Agregar moneda'
},
mail: {
host: 'Host de correo',
port: 'Puerto de correo',
driver: 'Conductor de correo',
password: 'Contraseña de correo',
username: 'Nombre de usuario de correo',
mail_config: 'Configuración de correo',
encryption: 'Cifrado de correo',
mail_config_desc: 'Los detalles a continuación se utilizarán para actualizar el entorno de correo. También puede cambiar los detalles en cualquier momento después de iniciar sesión.'
},
pdf: {
title: 'Configuración de PDF',
footer_text: 'Texto de pie de página',
@ -613,6 +628,7 @@ export default {
created_message: 'Impuesto sobre las ventas creado con éxito',
updated_message: 'Impuesto sobre ventas actualizado con éxito',
deleted_message: 'Impuesto sobre las ventas eliminado con éxito',
confirm_delete: 'No podrá recuperar este tipo de impuesto',
already_in_use: 'El impuesto ya está en uso.'
},
expense_category: {
@ -625,6 +641,7 @@ export default {
created_message: 'Categoría creada con éxito',
deleted_message: 'Categoría de gastos eliminada correctamente',
updated_message: 'Categoría de gastos actualizada con éxito',
confirm_delete: 'No podrá recuperar esta categoría de gastos',
already_in_use: 'La categoría ya está en uso.'
},
preferences: {
@ -742,7 +759,7 @@ export default {
numbers_only: 'Solo numeros.',
characters_only: 'Solo personajes.',
password_incorrect: 'Las contraseñas deben ser idénticas',
password_length: 'La contraseña debe tener 6 caracteres de longitud.',
password_length: 'La contraseña debe tener 5 caracteres de longitud.',
qty_must_greater_than_zero: 'La cantidad debe ser mayor que cero.',
price_greater_than_zero: 'El precio debe ser mayor que cero.',
payment_greater_than_zero: 'El pago debe ser mayor que cero.',

View File

@ -233,6 +233,10 @@ export default {
save_estimate: 'Sauvegarder lestimation',
confirm_conversion: 'Vous souhaitez convertir cette estimation en facture?',
conversion_message: 'Conversion réussie',
confirm_send_estimate: 'Cette estimation sera envoyée par courrier électronique au client.',
confirm_mark_as_sent: 'Cette estimation sera marquée comme envoyé',
confirm_mark_as_accepted: 'Cette estimation sera marquée comme acceptée',
confirm_mark_as_rejected: 'Cette estimation sera marquée comme Rejetée',
errors: {
required: 'Champ requis'
},
@ -308,6 +312,8 @@ export default {
invoice_template: 'Modèle de facture',
template: 'Modèle',
mark_as_sent: 'Marquer comme envoyé',
invoice_mark_as_sent: 'Cette facture sera marquée comme envoyé',
confirm_send: 'Cette facture sera envoyée par courrier électronique au client.',
invoice_date: 'Date de facturation',
record_payment: 'Record de paiement',
add_new_invoice: 'Ajouter une nouvelle facture',
@ -548,7 +554,17 @@ export default {
right: 'Droite',
left: 'La gauche',
action: 'action',
add_currency: 'Ajouter une devise',
add_currency: 'Ajouter une devise'
},
mail: {
host: 'Mail Host',
port: 'Port mail',
driver: 'Pilote de courrier',
password: 'Mot de passe mail',
username: "Mail Nom d'utilisateur",
mail_config: 'Configuration du courrier',
encryption: 'Chiffrement du courrier',
mail_config_desc: "Les détails ci-dessous seront utilisés pour mettre à jour l'environnement de messagerie. Aussi, vous pouvez modifier les détails à tout moment après la connexion."
},
pdf: {
title: 'Paramètre PDF',
@ -614,6 +630,7 @@ export default {
created_message: 'La taxe de vente créée avec succès',
updated_message: 'La taxe de vente a été mise à jour avec succès',
deleted_message: 'La taxe de vente a été supprimée avec succès',
confirm_delete: 'Vous ne pourrez pas récupérer ce type de taxe',
already_in_use: 'La taxe est déjà utilisée'
},
expense_category: {
@ -626,6 +643,7 @@ export default {
created_message: 'Catégorie créée avec succès',
deleted_message: 'La catégorie de dépenses a été supprimée avec succès',
updated_message: 'Catégorie de dépenses mise à jour avec succès',
confirm_delete: 'Vous ne pourrez pas récupérer cette catégorie de dépenses',
already_in_use: 'La catégorie est déjà utilisée'
},
preferences: {
@ -744,7 +762,7 @@ export default {
numbers_only: 'Chiffres uniquement.',
characters_only: 'Caractères seulement.',
password_incorrect: 'Les mots de passe doivent être identiques',
password_length: 'Le mot de passe doit comporter 6 caractères.',
password_length: 'Le mot de passe doit comporter 5 caractères.',
qty_must_greater_than_zero: 'La quantité doit être supérieure à zéro.',
price_greater_than_zero: 'Le prix doit être supérieur à zéro.',
payment_greater_than_zero: 'Le paiement doit être supérieur à zéro.',

View File

@ -72,6 +72,7 @@ import UserProfile from './views/settings/UserProfile.vue'
import TaxTypes from './views/settings/TaxTypes.vue'
import ExpenseCategory from './views/settings/ExpenseCategory.vue'
import MailConfig from './views/settings/MailConfig.vue'
import UpdateApp from './views/settings/UpdateApp.vue'
import Wizard from './views/wizard/Index.vue'
@ -337,6 +338,11 @@ const routes = [
path: 'notifications',
name: 'notifications',
component: Notifications
},
{
path: 'update-app',
name: 'updateapp',
component: UpdateApp
}
]
}

View File

@ -12,10 +12,15 @@
focus
type="email"
name="email"
@input="$v.loginData.email.$touch()"
/>
<div v-if="$v.loginData.email.$error">
<span v-if="!$v.loginData.email.required" class="text-danger">{{ $tc('validation.required') }}</span>
<span v-if="!$v.loginData.email.email" class="text-danger"> {{ $tc('validation.email_incorrect') }} </span>
<span v-if="!$v.loginData.email.required" class="text-danger">
{{ $tc('validation.required') }}
</span>
<span v-if="!$v.loginData.email.email" class="text-danger">
{{ $tc('validation.email_incorrect') }}
</span>
</div>
</div>
<div class="form-group">
@ -25,8 +30,10 @@
:invalid="$v.loginData.password.$error"
type="password"
name="password"
show-password
@input="$v.loginData.password.$touch()"
/>
<div v-if="$v.loginData.email.$error">
<div v-if="$v.loginData.password.$error">
<span v-if="!$v.loginData.password.required" class="text-danger">{{ $tc('validation.required') }}</span>
<span v-if="!$v.loginData.password.minLength" class="text-danger"> {{ $tc('validation.password_min_length', $v.loginData.password.$params.minLength.min, {count: $v.loginData.password.$params.minLength.min}) }} </span>
</div>
@ -91,7 +98,7 @@ export default {
},
password: {
required,
minLength: minLength(8)
minLength: minLength(5)
}
}
},

View File

@ -219,7 +219,7 @@
</div>
</div>
<hr> <!-- second row complete -->
<div class="row same-address-checkbox-container">
<div class="same-address-checkbox-container">
<div class="p-1">
<base-button ref="sameAddress" icon="copy" color="theme" class="btn-sm" @click="copyAddress(true)">
{{ $t('customers.copy_billing_address') }}
@ -624,17 +624,20 @@ export default {
this.isLoading = true
this.formData.currency_id = this.currency.id
}
let response = await this.addCustomer(this.formData)
if (response.data.success) {
window.toastr['success'](this.$t('customers.created_message'))
this.$router.push('/admin/customers')
this.isLoading = false
return true
try {
let response = await this.addCustomer(this.formData)
if (response.data.success) {
window.toastr['success'](this.$t('customers.created_message'))
this.$router.push('/admin/customers')
this.isLoading = false
return true
}
} catch (err) {
if (err.response.data.errors.email) {
this.isLoading = false
window.toastr['error'](this.$t('validation.email_already_taken'))
}
}
window.toastr['error'](response.data.error)
}
},
async fetchBillingState () {

View File

@ -343,7 +343,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('customers.confirm_delete'),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
@ -363,7 +363,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('customers.confirm_delete', 2),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {

View File

@ -1,5 +1,5 @@
<template>
<div id="app" class="main-content">
<div id="app" class="main-content dashboard">
<div class="row">
<div class="dash-item col-sm-6">
<router-link slot="item-title" to="/admin/invoices">
@ -177,7 +177,7 @@
<table-column
:sortable="false"
:filterable="false"
cell-class="action-dropdown no-click"
cell-class="action-dropdown dashboard-recent-invoice-options no-click"
>
<template slot-scope="row">
<v-dropdown>

View File

@ -249,25 +249,25 @@
{{ $t('estimates.convert_to_invoice') }}
</a>
</v-dropdown-item>
<v-dropdown-item>
<v-dropdown-item v-if="row.status !== 'SENT'">
<a class="dropdown-item" href="#" @click.self="onMarkAsSent(row.id)">
<font-awesome-icon icon="check-circle" class="dropdown-item-icon" />
{{ $t('estimates.mark_as_sent') }}
</a>
</v-dropdown-item>
<v-dropdown-item>
<v-dropdown-item v-if="row.status !== 'SENT'">
<a class="dropdown-item" href="#" @click.self="sendEstimate(row.id)">
<font-awesome-icon icon="paper-plane" class="dropdown-item-icon" />
{{ $t('estimates.send_estimate') }}
</a>
</v-dropdown-item>
<v-dropdown-item v-if="row.status === 'DRAFT'">
<v-dropdown-item v-if="row.status !== 'ACCEPTED'">
<a class="dropdown-item" href="#" @click.self="onMarkAsAccepted(row.id)">
<font-awesome-icon icon="check-circle" class="dropdown-item-icon" />
{{ $t('estimates.mark_as_accepted') }}
</a>
</v-dropdown-item>
<v-dropdown-item v-if="row.status === 'DRAFT'">
<v-dropdown-item v-if="row.status !== 'REJECTED'">
<a class="dropdown-item" href="#" @click.self="onMarkAsRejected(row.id)">
<font-awesome-icon icon="times-circle" class="dropdown-item-icon" />
{{ $t('estimates.mark_as_rejected') }}
@ -409,28 +409,48 @@ export default {
}
},
async onMarkAsAccepted (id) {
const data = {
id: id
}
let response = await this.markAsAccepted(data)
this.refreshTable()
if (response.data) {
this.filters.status = 'ACCEPTED'
this.$refs.table.refresh()
window.toastr['success'](this.$tc('estimates.marked_as_rejected_message'))
}
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_accepted'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true
}).then(async (markedAsRejected) => {
if (markedAsRejected) {
const data = {
id: id
}
let response = await this.markAsAccepted(data)
this.refreshTable()
if (response.data) {
this.filters.status = 'ACCEPTED'
this.$refs.table.refresh()
window.toastr['success'](this.$tc('estimates.marked_as_rejected_message'))
}
}
})
},
async onMarkAsRejected (id) {
const data = {
id: id
}
let response = await this.markAsRejected(data)
this.refreshTable()
if (response.data) {
this.filters.status = 'REJECTED'
this.$refs.table.refresh()
window.toastr['success'](this.$tc('estimates.marked_as_rejected_message'))
}
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_rejected'),
icon: '/assets/icon/times-circle-solid.svg',
buttons: true,
dangerMode: true
}).then(async (markedAsRejected) => {
if (markedAsRejected) {
const data = {
id: id
}
let response = await this.markAsRejected(data)
this.refreshTable()
if (response.data) {
this.filters.status = 'REJECTED'
this.$refs.table.refresh()
window.toastr['success'](this.$tc('estimates.marked_as_rejected_message'))
}
}
})
},
setFilters () {
this.filtersApplied = true
@ -470,7 +490,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('estimates.confirm_delete', 1),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
@ -491,11 +511,11 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_conversion'),
icon: 'error',
icon: '/assets/icon/envelope-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
if (willDelete) {
}).then(async (willConvertInToinvoice) => {
if (willConvertInToinvoice) {
let res = await this.convertToInvoice(id)
if (res.data) {
window.toastr['success'](this.$t('estimates.conversion_message'))
@ -510,7 +530,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('estimates.confirm_delete', 2),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
@ -536,24 +556,44 @@ export default {
this.refreshTable()
},
async onMarkAsSent (id) {
const data = {
id: id
}
let response = await this.markAsSent(data)
this.refreshTable()
if (response.data) {
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
}
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_sent'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willMarkAsSent) => {
if (willMarkAsSent) {
const data = {
id: id
}
let response = await this.markAsSent(data)
this.refreshTable()
if (response.data) {
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
}
}
})
},
async sendEstimate (id) {
const data = {
id: id
}
let response = await this.sendEmail(data)
this.refreshTable()
if (response.data) {
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
}
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_send_estimate'),
icon: '/assets/icon/paper-plane-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willSendEstimate) => {
if (willSendEstimate) {
const data = {
id: id
}
let response = await this.sendEmail(data)
this.refreshTable()
if (response.data) {
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
}
}
})
}
}
}

View File

@ -222,12 +222,22 @@ export default {
return true
},
async onMarkAsSent () {
this.isRequestOnGoing = true
let response = await this.markAsSent({id: this.estimate.id})
this.isRequestOnGoing = false
if (response.data) {
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
}
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_sent'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willMarkAsSent) => {
if (willMarkAsSent) {
this.isRequestOnGoing = true
let response = await this.markAsSent({id: this.estimate.id})
this.isRequestOnGoing = false
if (response.data) {
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
}
}
})
},
async removeEstimate (id) {
this.selectEstimate([parseInt(id)])
@ -235,7 +245,7 @@ export default {
swal({
title: 'Deleted',
text: 'you will not be able to recover this estimate!',
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {

View File

@ -358,7 +358,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('expenses.confirm_delete'),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
@ -378,7 +378,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('expenses.confirm_delete', 2),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {

View File

@ -247,13 +247,13 @@
{{ $t('invoices.view') }}
</router-link>
</v-dropdown-item>
<v-dropdown-item>
<v-dropdown-item v-if="row.status == 'DRAFT'">
<a class="dropdown-item" href="#" @click="sendInvoice(row.id)" >
<font-awesome-icon icon="paper-plane" class="dropdown-item-icon" />
{{ $t('invoices.send_invoice') }}
</a>
</v-dropdown-item>
<v-dropdown-item v-if="row.status === 'DRAFT'">
<v-dropdown-item v-if="row.status == 'DRAFT'">
<a class="dropdown-item" href="#" @click="sentInvoice(row.id)">
<font-awesome-icon icon="check-circle" class="dropdown-item-icon" />
{{ $t('invoices.mark_as_sent') }}
@ -384,24 +384,44 @@ export default {
'fetchCustomers'
]),
async sendInvoice (id) {
const data = {
id: id
}
let response = await this.sendEmail(data)
this.refreshTable()
if (response.data) {
window.toastr['success'](this.$tc('invoices.send_invoice'))
}
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.confirm_send'),
icon: '/assets/icon/paper-plane-solid.svg',
buttons: true,
dangerMode: true
}).then(async (Send_Invoice) => {
if (Send_Invoice) {
const data = {
id: id
}
let response = await this.sendEmail(data)
this.refreshTable()
if (response.data) {
window.toastr['success'](this.$tc('invoices.send_invoice'))
}
}
})
},
async sentInvoice (id) {
const data = {
id: id
}
let response = await this.markAsSent(data)
this.refreshTable()
if (response.data) {
window.toastr['success'](this.$tc('invoices.mark_as_sent'))
}
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.invoice_mark_as_sent'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true
}).then(async (MarkAsSend_Invoice) => {
if (MarkAsSend_Invoice) {
const data = {
id: id
}
let response = await this.markAsSent(data)
this.refreshTable()
if (response.data) {
window.toastr['success'](this.$tc('invoices.mark_as_sent'))
}
}
})
},
getStatus (val) {
this.filters.status = {
@ -476,7 +496,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('invoices.confirm_delete'),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
@ -506,7 +526,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('invoices.confirm_delete', 2),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {

View File

@ -229,12 +229,22 @@ export default {
return true
},
async onMarkAsSent () {
this.isRequestOnGoing = true
let response = await this.markAsSent({id: this.invoice.id})
this.isRequestOnGoing = false
if (response.data) {
window.toastr['success'](this.$tc('invoices.marked_as_sent_message'))
}
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.invoice_mark_as_sent'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true
}).then(async (MarkAsSend_Invoice) => {
if (MarkAsSend_Invoice) {
this.isRequestOnGoing = true
let response = await this.markAsSent({id: this.invoice.id})
this.isRequestOnGoing = false
if (response.data) {
window.toastr['success'](this.$tc('invoices.marked_as_sent_message'))
}
}
})
},
async removeInvoice (id) {
this.selectInvoice([parseInt(id)])
@ -242,7 +252,7 @@ export default {
swal({
title: 'Deleted',
text: 'you will not be able to recover this invoice!',
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {

View File

@ -362,7 +362,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('items.confirm_delete'),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
@ -388,7 +388,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('items.confirm_delete', 2),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {

View File

@ -101,7 +101,6 @@
</div>
<div v-if="$v.formData.amount.$error">
<span v-if="!$v.formData.amount.required" class="text-danger">{{ $t('validation.required') }}</span>
<span v-if="!$v.formData.amount.numeric" class="text-danger">{{ $t('validation.numbers_only') }}</span>
<span v-if="!$v.formData.amount.between && $v.formData.amount.numeric && amount <= 0" class="text-danger">{{ $t('validation.payment_greater_than_zero') }}</span>
<span v-if="!$v.formData.amount.between && amount > 0" class="text-danger">{{ $t('validation.payment_greater_than_due_amount') }}</span>
</div>
@ -156,7 +155,7 @@ import { mapActions, mapGetters } from 'vuex'
import MultiSelect from 'vue-multiselect'
import { validationMixin } from 'vuelidate'
import moment from 'moment'
const { required, numeric, between, maxLength } = require('vuelidate/lib/validators')
const { required, between, maxLength } = require('vuelidate/lib/validators')
export default {
components: { MultiSelect },
@ -201,7 +200,6 @@ export default {
},
amount: {
required,
numeric,
between: between(1, this.maxPayableAmount + 1)
},
notes: {

View File

@ -368,7 +368,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('payments.confirm_delete'),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
@ -388,7 +388,7 @@ export default {
swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('payments.confirm_delete', 2),
icon: 'error',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {

View File

@ -196,7 +196,14 @@ export default {
return true
},
downloadReport () {
this.url += '&download=true'
if (!this.getReports()) {
return false
}
if (navigator.appVersion.indexOf('Mac') !== -1) {
this.url += '&download=true'
} else {
window.open(this.getReportUrl + '&download=true')
}
setTimeout(() => {
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
}, 200)

View File

@ -200,7 +200,14 @@ export default {
return true
},
downloadReport () {
this.url += '&download=true'
if (!this.getReports()) {
return false
}
if (navigator.appVersion.indexOf('Mac') !== -1) {
this.url += '&download=true'
} else {
window.open(this.getReportUrl + '&download=true')
}
setTimeout(() => {
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
}, 200)

View File

@ -238,7 +238,14 @@ export default {
return true
},
downloadReport () {
this.url += '&download=true'
if (!this.getReports()) {
return false
}
if (navigator.appVersion.indexOf('Mac') !== -1) {
this.url += '&download=true'
} else {
window.open(this.getReportUrl + '&download=true')
}
setTimeout(() => {
if (this.selectedType === 'By Customer') {
this.url = `${this.customerSiteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`

View File

@ -189,14 +189,21 @@ export default {
this.$v.formData.$touch()
if (this.$v.$invalid) {
return true
return false
}
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
return true
},
downloadReport () {
this.url += '&download=true'
if (!this.getReports()) {
return false
}
if (navigator.appVersion.indexOf('Mac') !== -1) {
this.url += '&download=true'
} else {
window.open(this.url + '&download=true')
}
setTimeout(() => {
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
}, 200)

View File

@ -101,13 +101,23 @@ export default {
'deleteCategory'
]),
async removeExpenseCategory (id, index) {
let response = await this.deleteCategory(id)
if (response.data.success) {
window.toastr['success'](this.$tc('settings.expense_category.deleted_message'))
this.id = null
this.$refs.table.refresh()
return true
} window.toastr['success'](this.$t('settings.expense_category.already_in_use'))
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.expense_category.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
if (willDelete) {
let response = await this.deleteCategory(id)
if (response.data.success) {
window.toastr['success'](this.$tc('settings.expense_category.deleted_message'))
this.id = null
this.$refs.table.refresh()
return true
} window.toastr['error'](this.$t('settings.expense_category.already_in_use'))
}
})
},
openCategoryModal () {
this.openModal({

View File

@ -8,7 +8,7 @@
</p>
</div>
<form action="" @submit.prevent="saveEmailConfig()">
<div class="row my-2 mt-5">
<div class="row">
<div class="col-md-6 my-2">
<label class="form-label">{{ $t('settings.mail.driver') }}</label>
<span class="text-danger"> *</span>
@ -117,7 +117,7 @@
</div>
<base-button
:loading="loading"
class="pull-right mt-5"
class="pull-right mt-4"
icon="save"
color="theme"
type="submit"

View File

@ -29,16 +29,9 @@
>
<table-column
:sortable="true"
:filterable="true"
:label="$t('settings.tax_types.tax_name')"
>
<template slot-scope="row">
<span>{{ $t('settings.tax_types.tax_name') }}</span>
<span class="tax-name">
{{ row.name }}
</span>
</template>
</table-column>
show="name"
/>
<table-column
:sortable="true"
:filterable="true"
@ -159,13 +152,23 @@ export default {
}
},
async removeTax (id, index) {
let response = await this.deleteTaxType(id)
if (response.data.success) {
window.toastr['success'](this.$t('settings.tax_types.deleted_message'))
this.id = null
this.$refs.table.refresh()
return true
}window.toastr['success'](this.$t('settings.tax_types.already_in_use'))
swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.tax_types.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
if (willDelete) {
let response = await this.deleteTaxType(id)
if (response.data.success) {
window.toastr['success'](this.$t('settings.tax_types.deleted_message'))
this.id = null
this.$refs.table.refresh()
return true
}window.toastr['error'](this.$t('settings.tax_types.already_in_use'))
}
})
},
openTaxModal () {
this.openModal({

View File

@ -0,0 +1,55 @@
<template>
<div class="setting-main-container">
<div class="card setting-card">
<div class="page-header">
<h3 class="page-title">{{ $t('settings.update_app.title') }}</h3>
<p class="page-sub-title">
{{ $t('settings.update_app.description') }}
</p>
<base-button size="large" icon="sync-alt" color="theme" @click="onUpdateApp">
{{ $t('settings.update_app.update') }}
</base-button>
<div v-if="isShowProgressBar" class="progress mt-4">
<div
:style="[{'width': progress+'%'}]"
class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="100"
/>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
isShowProgressBar: false,
progress: 10,
interval: null
}
},
watch: {
},
mounted () {
},
methods: {
onUpdateApp () {
this.isShowProgressBar = true
this.interval = setInterval(() => {
if (this.progress >= 100) {
clearInterval(this.interval)
setTimeout(() => {
this.isShowProgressBar = false
}, 1000)
}
this.progress += 10
}, 250)
}
}
}
</script>

View File

@ -43,6 +43,9 @@
type="password"
@input="$v.formData.password.$touch()"
/>
<div v-if="$v.formData.password.$error">
<span v-if="!$v.formData.password.minLength" class="text-danger"> {{ $tc('validation.password_min_length', $v.formData.password.$params.minLength.min, {count: $v.formData.password.$params.minLength.min}) }} </span>
</div>
</div>
<div class="col-md-6 mb-4 form-group">
<label class="input-label">{{ $tc('settings.account_settings.confirm_password') }}</label>
@ -78,7 +81,7 @@
<script>
import { validationMixin } from 'vuelidate'
import { mapActions } from 'vuex'
const { required, requiredIf, sameAs, email } = require('vuelidate/lib/validators')
const { required, requiredIf, sameAs, email, minLength } = require('vuelidate/lib/validators')
export default {
mixins: [validationMixin],
@ -103,6 +106,7 @@ export default {
email
},
password: {
minLength: minLength(5)
},
confirm_password: {
required: requiredIf('isRequired'),

View File

@ -74,6 +74,12 @@ export default {
title: 'settings.menu_title.notifications',
icon: 'bell',
iconType: 'far'
},
{
link: '/admin/settings/update-app',
title: 'settings.menu_title.update_app',
icon: 'sync-alt',
iconType: 'fas'
}
]
}

View File

@ -94,17 +94,27 @@
<div class="col-md-6">
<label class="form-label">{{ $t('wizard.address') }}</label>
<base-text-area
:invalid="$v.companyData.address_street_1.$error"
v-model.trim="companyData.address_street_1"
:placeholder="$t('general.street_1')"
name="billing_street1"
rows="2"
@input="$v.companyData.address_street_1.$touch()"
/>
<div v-if="$v.companyData.address_street_1.$error">
<span v-if="!$v.companyData.address_street_1.maxLength" class="text-danger">{{ $t('validation.description_maxlength') }}</span>
</div>
<base-text-area
:invalid="$v.companyData.address_street_2.$error"
v-model="companyData.address_street_2"
:placeholder="$t('general.street_2')"
name="billing_street2"
rows="2"
@input="$v.companyData.address_street_2.$touch()"
/>
<div v-if="$v.companyData.address_street_2.$error">
<span v-if="!$v.companyData.address_street_2.maxLength" class="text-danger">{{ $t('validation.description_maxlength') }}</span>
</div>
</div>
<div class="col-md-6">
<div class="row">
@ -146,7 +156,7 @@ import MultiSelect from 'vue-multiselect'
import AvatarCropper from 'vue-avatar-cropper'
import { validationMixin } from 'vuelidate'
import Ls from '../../services/ls'
const { required, minLength, email } = require('vuelidate/lib/validators')
const { required, minLength, email, maxLength } = require('vuelidate/lib/validators')
export default {
components: {
@ -197,6 +207,12 @@ export default {
},
country_id: {
required
},
address_street_1: {
maxLength: maxLength(255)
},
address_street_2: {
maxLength: maxLength(255)
}
}
},

View File

@ -45,6 +45,7 @@
/>
<div v-if="$v.profileData.password.$error">
<span v-if="!$v.profileData.password.required" class="text-danger">{{ $tc('validation.required') }}</span>
<span v-if="!$v.profileData.password.minLength" class="text-danger"> {{ $tc('validation.password_min_length', $v.profileData.password.$params.minLength.min, {count: $v.profileData.password.$params.minLength.min}) }} </span>
</div>
</div>
<div class="col-md-6">
@ -106,7 +107,8 @@ export default {
required
},
password: {
required
required,
minLength: minLength(5)
},
confirm_password: {
required: requiredIf('isRequired'),