mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-28 20:21:10 -04:00
Merge branch 'auto-update' of https://gitlab.com/mohit.panjvani/crater-web into auto-update
This commit is contained in:
@ -35,9 +35,7 @@ class EnvironmentController extends Controller
|
|||||||
{
|
{
|
||||||
$results = $this->EnvironmentManager->saveDatabaseVariables($request);
|
$results = $this->EnvironmentManager->saveDatabaseVariables($request);
|
||||||
|
|
||||||
|
|
||||||
if(array_key_exists("success", $results)) {
|
if(array_key_exists("success", $results)) {
|
||||||
|
|
||||||
Artisan::call('config:clear');
|
Artisan::call('config:clear');
|
||||||
Artisan::call('key:generate --force');
|
Artisan::call('key:generate --force');
|
||||||
Artisan::call('migrate --seed');
|
Artisan::call('migrate --seed');
|
||||||
|
|||||||
@ -203,7 +203,7 @@ class OnboardingController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Setting::setSetting('version','1.0.0');
|
Setting::setSetting('version', config('crater.version'));
|
||||||
|
|
||||||
Artisan::call('passport:install --force');
|
Artisan::call('passport:install --force');
|
||||||
|
|
||||||
|
|||||||
@ -49,12 +49,20 @@ class EnvironmentManager
|
|||||||
'DB_PASSWORD='.$request->database_password."\n\n";
|
'DB_PASSWORD='.$request->database_password."\n\n";
|
||||||
|
|
||||||
if (! $this->checkDatabaseConnection($request)) {
|
if (! $this->checkDatabaseConnection($request)) {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'error' => 'connection_failed'
|
'error' => 'connection_failed'
|
||||||
];
|
];
|
||||||
|
} else {
|
||||||
|
if(count(DB::connection()->select('SHOW TABLES'))) {
|
||||||
|
return [
|
||||||
|
'error' => 'database_should_be_empty'
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
file_put_contents($this->envPath, str_replace(
|
file_put_contents($this->envPath, str_replace(
|
||||||
$oldDatabaseData,
|
$oldDatabaseData,
|
||||||
$newDatabaseData,
|
$newDatabaseData,
|
||||||
@ -101,7 +109,7 @@ class EnvironmentManager
|
|||||||
'MAIL_USERNAME='.$request->mail_username."\n".
|
'MAIL_USERNAME='.$request->mail_username."\n".
|
||||||
'MAIL_PASSWORD='.$request->mail_password."\n".
|
'MAIL_PASSWORD='.$request->mail_password."\n".
|
||||||
'MAIL_ENCRYPTION='.$request->mail_encryption."\n\n";
|
'MAIL_ENCRYPTION='.$request->mail_encryption."\n\n";
|
||||||
// dd($newMailData);
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
file_put_contents($this->envPath, str_replace(
|
file_put_contents($this->envPath, str_replace(
|
||||||
|
|||||||
@ -40,8 +40,8 @@ class Updater
|
|||||||
// Create temp directory
|
// Create temp directory
|
||||||
$path = 'temp-' . md5(mt_rand());
|
$path = 'temp-' . md5(mt_rand());
|
||||||
$path2 = 'temp2-' . md5(mt_rand());
|
$path2 = 'temp2-' . md5(mt_rand());
|
||||||
$temp_path = storage_path('app/temp') . '/' . $path;
|
$temp_path = storage_path('app') . '/' . $path;
|
||||||
$temp_path2 = storage_path('app/temp') . '/' . $path2;
|
$temp_path2 = storage_path('app') . '/' . $path2;
|
||||||
|
|
||||||
if (!File::isDirectory($temp_path)) {
|
if (!File::isDirectory($temp_path)) {
|
||||||
File::makeDirectory($temp_path);
|
File::makeDirectory($temp_path);
|
||||||
|
|||||||
14
config/crater.php
Normal file
14
config/crater.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Crater Requirements
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'version' => '1.0.0',
|
||||||
|
|
||||||
|
];
|
||||||
@ -1,9 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<button :type="type" :class="btnClass" :disabled="disabled" @click="handleClick">
|
<button
|
||||||
<font-awesome-icon v-if="icon && !loading && !rightIcon" :class="iconClass" :icon="icon" class="vue-icon icon-left" />
|
:type="type"
|
||||||
<font-awesome-icon v-if="loading" :class="iconClass" icon="spinner" class="fa-spin"/>
|
:class="btnClass"
|
||||||
|
:disabled="disabled || loading"
|
||||||
|
@click="handleClick"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
v-if="icon && !loading && !rightIcon"
|
||||||
|
:class="iconClass"
|
||||||
|
:icon="icon"
|
||||||
|
class="vue-icon icon-left"
|
||||||
|
/>
|
||||||
|
<font-awesome-icon
|
||||||
|
v-if="loading"
|
||||||
|
:class="iconClass"
|
||||||
|
icon="spinner"
|
||||||
|
class="fa-spin"
|
||||||
|
/>
|
||||||
<slot />
|
<slot />
|
||||||
<font-awesome-icon v-if="icon && !loading && rightIcon" :class="iconClass" :icon="icon" class="vue-icon icon-right" />
|
<font-awesome-icon
|
||||||
|
v-if="icon && !loading && rightIcon"
|
||||||
|
:class="iconClass"
|
||||||
|
:icon="icon"
|
||||||
|
class="vue-icon icon-right"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div v-if="modalActive" class="base-modal" :class="'size-' + modalSize">
|
<div v-if="modalActive" :class="'size-' + modalSize" class="base-modal">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="close-icon">
|
<div class="close-icon">
|
||||||
<font-awesome-icon class="mr-2" icon="times" @click="closeModal"/>
|
<font-awesome-icon class="mr-2" icon="times" @click="closeModal"/>
|
||||||
|
|||||||
@ -233,6 +233,8 @@ export default {
|
|||||||
confirm_mark_as_accepted: 'This estimate will be marked as Accepted',
|
confirm_mark_as_accepted: 'This estimate will be marked as Accepted',
|
||||||
confirm_mark_as_rejected: 'This estimate will be marked as Rejected',
|
confirm_mark_as_rejected: 'This estimate will be marked as Rejected',
|
||||||
no_matching_estimates: 'There are no matching estimates!',
|
no_matching_estimates: 'There are no matching estimates!',
|
||||||
|
mark_as_sent_successfully: 'Estimate marked as sent successfully',
|
||||||
|
send_estimate_successfully: 'Estimate sent successfully',
|
||||||
errors: {
|
errors: {
|
||||||
required: 'Field is required'
|
required: 'Field is required'
|
||||||
},
|
},
|
||||||
@ -323,6 +325,8 @@ export default {
|
|||||||
list_of_invoices: 'This section will contain the list of invoices.',
|
list_of_invoices: 'This section will contain the list of invoices.',
|
||||||
select_invoice: 'Select Invoice',
|
select_invoice: 'Select Invoice',
|
||||||
no_matching_invoices: 'There are no matching invoices!',
|
no_matching_invoices: 'There are no matching invoices!',
|
||||||
|
mark_as_sent_successfully: 'Invoice marked as sent successfully',
|
||||||
|
send_invoice_successfully: 'Invoice sent successfully',
|
||||||
item: {
|
item: {
|
||||||
title: 'Item Title',
|
title: 'Item Title',
|
||||||
description: 'Description',
|
description: 'Description',
|
||||||
@ -738,7 +742,8 @@ export default {
|
|||||||
migrate_failed: 'Migrate Failed',
|
migrate_failed: 'Migrate Failed',
|
||||||
database_variables_save_error: 'Unable to connect to the DB with Provided Values.',
|
database_variables_save_error: 'Unable to connect to the DB with Provided Values.',
|
||||||
mail_variables_save_error: 'Email configuration failed.',
|
mail_variables_save_error: 'Email configuration failed.',
|
||||||
connection_failed: 'Database Connection Failed'
|
connection_failed: 'Database connection failed',
|
||||||
|
database_should_be_empty: 'Database should be empty'
|
||||||
},
|
},
|
||||||
success: {
|
success: {
|
||||||
mail_variables_save_successfully: 'Email configured successfully',
|
mail_variables_save_successfully: 'Email configured successfully',
|
||||||
|
|||||||
@ -237,6 +237,8 @@ export default {
|
|||||||
confirm_mark_as_sent: 'Esta estimación se marcará como enviada',
|
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_accepted: 'Esta estimación se marcará como Aceptada',
|
||||||
confirm_mark_as_rejected: 'Esta estimación se marcará como Rechazada',
|
confirm_mark_as_rejected: 'Esta estimación se marcará como Rechazada',
|
||||||
|
mark_as_sent_successfully: 'Estimación marcada como enviada correctamente',
|
||||||
|
send_estimate_successfully: 'Estimación enviada con éxito',
|
||||||
errors: {
|
errors: {
|
||||||
required: 'Se requiere campo'
|
required: 'Se requiere campo'
|
||||||
},
|
},
|
||||||
@ -326,6 +328,8 @@ export default {
|
|||||||
no_invoices: '¡Aún no hay facturas!',
|
no_invoices: '¡Aún no hay facturas!',
|
||||||
list_of_invoices: 'Esta sección contendrá la lista de facturas.',
|
list_of_invoices: 'Esta sección contendrá la lista de facturas.',
|
||||||
select_invoice: 'Seleccionar factura',
|
select_invoice: 'Seleccionar factura',
|
||||||
|
mark_as_sent_successfully: 'Factura marcada como enviada con éxito',
|
||||||
|
send_invoice_successfully: 'Factura enviada exitosamente',
|
||||||
item: {
|
item: {
|
||||||
title: 'Título del artículo',
|
title: 'Título del artículo',
|
||||||
description: 'Descripción',
|
description: 'Descripción',
|
||||||
|
|||||||
@ -237,6 +237,8 @@ export default {
|
|||||||
confirm_mark_as_sent: 'Cette estimation sera marquée comme envoyé',
|
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_accepted: 'Cette estimation sera marquée comme acceptée',
|
||||||
confirm_mark_as_rejected: 'Cette estimation sera marquée comme Rejetée',
|
confirm_mark_as_rejected: 'Cette estimation sera marquée comme Rejetée',
|
||||||
|
mark_as_sent_successfully: 'Estimation marquée comme envoyée avec succès',
|
||||||
|
send_estimate_successfully: 'Estimation envoyée avec succès',
|
||||||
errors: {
|
errors: {
|
||||||
required: 'Champ requis'
|
required: 'Champ requis'
|
||||||
},
|
},
|
||||||
@ -326,6 +328,8 @@ export default {
|
|||||||
no_invoices: 'Aucune facture pour le moment!',
|
no_invoices: 'Aucune facture pour le moment!',
|
||||||
list_of_invoices: 'Cette section contiendra la liste des factures.',
|
list_of_invoices: 'Cette section contiendra la liste des factures.',
|
||||||
select_invoice: 'Sélectionnez facture',
|
select_invoice: 'Sélectionnez facture',
|
||||||
|
mark_as_sent_successfully: 'Facture marquée comme envoyée avec succès',
|
||||||
|
send_invoice_successfully: 'Facture envoyée avec succès',
|
||||||
item: {
|
item: {
|
||||||
title: 'Titre de larticle',
|
title: 'Titre de larticle',
|
||||||
description: 'La description',
|
description: 'La description',
|
||||||
|
|||||||
@ -396,7 +396,7 @@ export default {
|
|||||||
swal({
|
swal({
|
||||||
title: this.$t('general.are_you_sure'),
|
title: this.$t('general.are_you_sure'),
|
||||||
text: this.$tc('estimates.confirm_delete', 1),
|
text: this.$tc('estimates.confirm_delete', 1),
|
||||||
icon: 'error',
|
icon: '/assets/icon/trash-solid.svg',
|
||||||
buttons: true,
|
buttons: true,
|
||||||
dangerMode: true
|
dangerMode: true
|
||||||
}).then(async (willDelete) => {
|
}).then(async (willDelete) => {
|
||||||
@ -416,7 +416,7 @@ export default {
|
|||||||
swal({
|
swal({
|
||||||
title: this.$t('general.are_you_sure'),
|
title: this.$t('general.are_you_sure'),
|
||||||
text: this.$t('estimates.confirm_conversion'),
|
text: this.$t('estimates.confirm_conversion'),
|
||||||
icon: 'error',
|
icon: '/assets/icon/envelope-solid.svg',
|
||||||
buttons: true,
|
buttons: true,
|
||||||
dangerMode: true
|
dangerMode: true
|
||||||
}).then(async (willDelete) => {
|
}).then(async (willDelete) => {
|
||||||
@ -433,14 +433,24 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
async onMarkAsSent (id) {
|
async onMarkAsSent (id) {
|
||||||
const data = {
|
swal({
|
||||||
id: id
|
title: this.$t('general.are_you_sure'),
|
||||||
}
|
text: this.$t('estimates.confirm_mark_as_sent'),
|
||||||
let response = await this.markAsSent(data)
|
icon: '/assets/icon/check-circle-solid.svg',
|
||||||
this.$refs.table.refresh()
|
buttons: true,
|
||||||
if (response.data) {
|
dangerMode: true
|
||||||
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
|
}).then(async (willMarkAsSent) => {
|
||||||
}
|
if (willMarkAsSent) {
|
||||||
|
const data = {
|
||||||
|
id: id
|
||||||
|
}
|
||||||
|
let response = await this.markAsSent(data)
|
||||||
|
this.$refs.table.refresh()
|
||||||
|
if (response.data) {
|
||||||
|
window.toastr['success'](this.$tc('estimates.mark_as_sent_successfully'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async removeInvoice (id) {
|
async removeInvoice (id) {
|
||||||
@ -448,7 +458,7 @@ export default {
|
|||||||
swal({
|
swal({
|
||||||
title: this.$t('general.are_you_sure'),
|
title: this.$t('general.are_you_sure'),
|
||||||
text: this.$tc('invoices.confirm_delete'),
|
text: this.$tc('invoices.confirm_delete'),
|
||||||
icon: 'error',
|
icon: '/assets/icon/trash-solid.svg',
|
||||||
buttons: true,
|
buttons: true,
|
||||||
dangerMode: true
|
dangerMode: true
|
||||||
}).then(async (willDelete) => {
|
}).then(async (willDelete) => {
|
||||||
@ -465,24 +475,44 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async sendInvoice (id) {
|
async sendInvoice (id) {
|
||||||
const data = {
|
swal({
|
||||||
id: id
|
title: this.$t('general.are_you_sure'),
|
||||||
}
|
text: this.$t('invoices.confirm_send'),
|
||||||
let response = await this.sendEmail(data)
|
icon: '/assets/icon/paper-plane-solid.svg',
|
||||||
this.$refs.table.refresh()
|
buttons: true,
|
||||||
if (response.data) {
|
dangerMode: true
|
||||||
window.toastr['success'](this.$tc('invoices.send_invoice'))
|
}).then(async (willSendInvoice) => {
|
||||||
}
|
if (willSendInvoice) {
|
||||||
|
const data = {
|
||||||
|
id: id
|
||||||
|
}
|
||||||
|
let response = await this.sendEmail(data)
|
||||||
|
this.$refs.table.refresh()
|
||||||
|
if (response.data) {
|
||||||
|
window.toastr['success'](this.$tc('invoices.send_invoice_successfully'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async sentInvoice (id) {
|
async sentInvoice (id) {
|
||||||
const data = {
|
swal({
|
||||||
id: id
|
title: this.$t('general.are_you_sure'),
|
||||||
}
|
text: this.$t('invoices.invoice_mark_as_sent'),
|
||||||
let response = await this.markAsSent(data)
|
icon: '/assets/icon/check-circle-solid.svg',
|
||||||
this.$refs.table.refresh()
|
buttons: true,
|
||||||
if (response.data) {
|
dangerMode: true
|
||||||
window.toastr['success'](this.$tc('invoices.mark_as_sent'))
|
}).then(async (willMarkAsSend) => {
|
||||||
}
|
if (willMarkAsSend) {
|
||||||
|
const data = {
|
||||||
|
id: id
|
||||||
|
}
|
||||||
|
let response = await this.markAsSent(data)
|
||||||
|
this.$refs.table.refresh()
|
||||||
|
if (response.data) {
|
||||||
|
window.toastr['success'](this.$tc('invoices.mark_as_sent_successfully'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -553,6 +553,8 @@ export default {
|
|||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.selectCustomer(response.data.estimate.user_id)
|
this.selectCustomer(response.data.estimate.user_id)
|
||||||
this.newEstimate = response.data.estimate
|
this.newEstimate = response.data.estimate
|
||||||
|
this.newEstimate.estimate_date = moment(response.data.estimate.estimate_date, 'YYYY-MM-DD').toString()
|
||||||
|
this.newEstimate.expiry_date = moment(response.data.estimate.expiry_date, 'YYYY-MM-DD').toString()
|
||||||
this.discountPerItem = response.data.discount_per_item
|
this.discountPerItem = response.data.discount_per_item
|
||||||
this.taxPerItem = response.data.tax_per_item
|
this.taxPerItem = response.data.tax_per_item
|
||||||
this.selectedCurrency = this.defaultCurrency
|
this.selectedCurrency = this.defaultCurrency
|
||||||
|
|||||||
@ -425,7 +425,7 @@ export default {
|
|||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.filters.status = 'ACCEPTED'
|
this.filters.status = 'ACCEPTED'
|
||||||
this.$refs.table.refresh()
|
this.$refs.table.refresh()
|
||||||
window.toastr['success'](this.$tc('estimates.marked_as_rejected_message'))
|
window.toastr['success'](this.$tc('estimates.confirm_mark_as_accepted'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -570,7 +570,7 @@ export default {
|
|||||||
let response = await this.markAsSent(data)
|
let response = await this.markAsSent(data)
|
||||||
this.refreshTable()
|
this.refreshTable()
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
|
window.toastr['success'](this.$tc('estimates.mark_as_sent_successfully'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -590,7 +590,7 @@ export default {
|
|||||||
let response = await this.sendEmail(data)
|
let response = await this.sendEmail(data)
|
||||||
this.refreshTable()
|
this.refreshTable()
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
|
window.toastr['success'](this.$tc('estimates.send_estimate_successfully'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
<div class="page-actions row">
|
<div class="page-actions row">
|
||||||
<div class="col-xs-2">
|
<div class="col-xs-2">
|
||||||
<base-button
|
<base-button
|
||||||
|
v-if="estimate.status !== 'SENT'"
|
||||||
:loading="isRequestOnGoing"
|
:loading="isRequestOnGoing"
|
||||||
:disabled="isRequestOnGoing"
|
:disabled="isRequestOnGoing"
|
||||||
:outline="true"
|
:outline="true"
|
||||||
@ -33,7 +34,7 @@
|
|||||||
</v-dropdown>
|
</v-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="estimate-sidebar">
|
<div class="estimate-si debar">
|
||||||
<base-loader v-if="isSearching" />
|
<base-loader v-if="isSearching" />
|
||||||
<div v-else class="side-header">
|
<div v-else class="side-header">
|
||||||
<base-input
|
<base-input
|
||||||
@ -144,6 +145,8 @@ export default {
|
|||||||
orderByField: null,
|
orderByField: null,
|
||||||
searchText: null
|
searchText: null
|
||||||
},
|
},
|
||||||
|
status: ['DRAFT', 'SENT', 'VIEWED', 'EXPIRED', 'ACCEPTED', 'REJECTED'],
|
||||||
|
isMarkAsSent: false,
|
||||||
isRequestOnGoing: false,
|
isRequestOnGoing: false,
|
||||||
isSearching: false
|
isSearching: false
|
||||||
}
|
}
|
||||||
@ -230,11 +233,11 @@ export default {
|
|||||||
dangerMode: true
|
dangerMode: true
|
||||||
}).then(async (willMarkAsSent) => {
|
}).then(async (willMarkAsSent) => {
|
||||||
if (willMarkAsSent) {
|
if (willMarkAsSent) {
|
||||||
this.isRequestOnGoing = true
|
this.isMarkAsSent = true
|
||||||
let response = await this.markAsSent({id: this.estimate.id})
|
let response = await this.markAsSent({id: this.estimate.id})
|
||||||
this.isRequestOnGoing = false
|
this.isMarkAsSent = false
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
|
window.toastr['success'](this.$tc('estimates.mark_as_sent_successfully'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -554,6 +554,8 @@ export default {
|
|||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.selectCustomer(response.data.invoice.user_id)
|
this.selectCustomer(response.data.invoice.user_id)
|
||||||
this.newInvoice = response.data.invoice
|
this.newInvoice = response.data.invoice
|
||||||
|
this.newInvoice.invoice_date = moment(response.data.invoice.invoice_date, 'YYYY-MM-DD').toString()
|
||||||
|
this.newInvoice.due_date = moment(response.data.invoice.due_date, 'YYYY-MM-DD').toString()
|
||||||
this.discountPerItem = response.data.discount_per_item
|
this.discountPerItem = response.data.discount_per_item
|
||||||
this.taxPerItem = response.data.tax_per_item
|
this.taxPerItem = response.data.tax_per_item
|
||||||
this.selectedCurrency = this.defaultCurrency
|
this.selectedCurrency = this.defaultCurrency
|
||||||
|
|||||||
@ -390,15 +390,15 @@ export default {
|
|||||||
icon: '/assets/icon/paper-plane-solid.svg',
|
icon: '/assets/icon/paper-plane-solid.svg',
|
||||||
buttons: true,
|
buttons: true,
|
||||||
dangerMode: true
|
dangerMode: true
|
||||||
}).then(async (Send_Invoice) => {
|
}).then(async (willSendInvoice) => {
|
||||||
if (Send_Invoice) {
|
if (willSendInvoice) {
|
||||||
const data = {
|
const data = {
|
||||||
id: id
|
id: id
|
||||||
}
|
}
|
||||||
let response = await this.sendEmail(data)
|
let response = await this.sendEmail(data)
|
||||||
this.refreshTable()
|
this.refreshTable()
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
window.toastr['success'](this.$tc('invoices.send_invoice'))
|
window.toastr['success'](this.$tc('invoices.send_invoice_successfully'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -410,15 +410,15 @@ export default {
|
|||||||
icon: '/assets/icon/check-circle-solid.svg',
|
icon: '/assets/icon/check-circle-solid.svg',
|
||||||
buttons: true,
|
buttons: true,
|
||||||
dangerMode: true
|
dangerMode: true
|
||||||
}).then(async (MarkAsSend_Invoice) => {
|
}).then(async (willMarkAsSend) => {
|
||||||
if (MarkAsSend_Invoice) {
|
if (willMarkAsSend) {
|
||||||
const data = {
|
const data = {
|
||||||
id: id
|
id: id
|
||||||
}
|
}
|
||||||
let response = await this.markAsSent(data)
|
let response = await this.markAsSent(data)
|
||||||
this.refreshTable()
|
this.refreshTable()
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
window.toastr['success'](this.$tc('invoices.mark_as_sent'))
|
window.toastr['success'](this.$tc('invoices.mark_as_sent_successfully'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -97,7 +97,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label">{{ $t('wizard.database.password') }}</label>
|
<label class="form-label">{{ $t('wizard.database.password') }}</label>
|
||||||
<span class="text-danger"> *</span>
|
|
||||||
<base-input
|
<base-input
|
||||||
v-model.trim="databaseData.database_password"
|
v-model.trim="databaseData.database_password"
|
||||||
type="password"
|
type="password"
|
||||||
@ -154,7 +153,7 @@ export default {
|
|||||||
database_name: null,
|
database_name: null,
|
||||||
database_username: null,
|
database_username: null,
|
||||||
database_password: null,
|
database_password: null,
|
||||||
app_url: null
|
app_url: window.location.origin
|
||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
connections: [
|
connections: [
|
||||||
@ -207,8 +206,8 @@ export default {
|
|||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e.response)
|
||||||
window.toastr['error']('Something went wrong')
|
window.toastr['error'](e.response.data.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,8 +67,8 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
tab: 'step_1',
|
tab: 'step_3',
|
||||||
step: 1
|
step: 3
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<base-button
|
<base-button
|
||||||
v-if="requirements"
|
v-if="hasNext"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
class="pull-right mt-4"
|
class="pull-right mt-4"
|
||||||
icon="arrow-right"
|
icon="arrow-right"
|
||||||
@ -46,7 +46,7 @@
|
|||||||
{{ $t('wizard.continue') }}
|
{{ $t('wizard.continue') }}
|
||||||
</base-button>
|
</base-button>
|
||||||
<base-button
|
<base-button
|
||||||
v-else
|
v-if="!requirements"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
class="pull-right mt-4"
|
class="pull-right mt-4"
|
||||||
color="theme"
|
color="theme"
|
||||||
@ -74,6 +74,20 @@ export default {
|
|||||||
isShow: true
|
isShow: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
hasNext () {
|
||||||
|
if (this.requirements) {
|
||||||
|
let isRequired = true
|
||||||
|
for (const key in this.requirements) {
|
||||||
|
if (!this.requirements[key]) {
|
||||||
|
isRequired = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.requirements && this.phpSupportInfo.supported && isRequired
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
listToggle () {
|
listToggle () {
|
||||||
this.isShow = !this.isShow
|
this.isShow = !this.isShow
|
||||||
|
|||||||
@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex:1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@ -445,6 +446,9 @@
|
|||||||
.estimate-amount {
|
.estimate-amount {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: #55547A;
|
color: #55547A;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.total {
|
.total {
|
||||||
|
|||||||
@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@ -445,6 +446,9 @@
|
|||||||
.invoice-amount {
|
.invoice-amount {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: #55547A;
|
color: #55547A;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.total {
|
.total {
|
||||||
|
|||||||
@ -263,7 +263,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr.main-table-header th {
|
tr.main-table-header th {
|
||||||
border-bottom: 1px solid #EAF1FB;
|
border-bottom: 0.620315px solid #E8E8E8;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|||||||
@ -264,7 +264,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr.main-table-header th {
|
tr.main-table-header th {
|
||||||
border-bottom: 1px solid #EAF1FB;
|
border-bottom: 0.620315px solid #E8E8E8;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
<div class="notes">
|
@if ($estimate->notes != '' && $estimate->notes != null)
|
||||||
<div class="notes-label">
|
<div class="notes">
|
||||||
Notes
|
<div class="notes-label">
|
||||||
|
Notes
|
||||||
|
</div>
|
||||||
|
{{$estimate->notes}}
|
||||||
</div>
|
</div>
|
||||||
{{$estimate->notes}}
|
@endif
|
||||||
</div>
|
|
||||||
|
|||||||
@ -1,27 +1,32 @@
|
|||||||
<table width="100%" class="table2" cellspacing="0" border="0">
|
<table width="100%" class="table2" cellspacing="0" border="0">
|
||||||
<tr class="main-table-header">
|
<tr class="main-table-header">
|
||||||
|
<th class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">#</th>
|
||||||
@if($estimate->discount_per_item === 'NO')
|
@if($estimate->discount_per_item === 'NO')
|
||||||
<th width="80%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
|
<th width="80%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
|
||||||
@else
|
@else
|
||||||
<th width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
|
<th width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
|
||||||
@endif
|
@endif
|
||||||
<th width="17%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Quantity</th>
|
<th width="17%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Quantity</th>
|
||||||
<th width="18%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 40px">Price</th>
|
<th width="18%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 40px">Price</th>
|
||||||
@if($estimate->discount_per_item === 'YES')
|
@if($estimate->discount_per_item === 'YES')
|
||||||
<th width="10%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 10px">Discount</th>
|
<th width="10%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-left: 10px">Discount</th>
|
||||||
@endif
|
@endif
|
||||||
<th width="15%" class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</th>
|
<th width="15%" class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@php
|
||||||
|
$index = 1
|
||||||
|
@endphp
|
||||||
@foreach ($estimate->items as $item)
|
@foreach ($estimate->items as $item)
|
||||||
<tr class="item-details">
|
<tr class="item-details">
|
||||||
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px; vertical-align: top;">{{$index}}</td>
|
||||||
<td class="inv-item items" style="text-align: left; color: #040405;padding-left: 0px">
|
<td class="inv-item items" style="text-align: left; color: #040405;padding-left: 0px">
|
||||||
<span>{{ $item->name }}</span><br>
|
<span>{{ $item->name }}</span><br>
|
||||||
<span style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{{ $item->description }}</span>
|
<span style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{{ $item->description }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px">{{$item->quantity}}</td>
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px">{{$item->quantity}}</td>
|
||||||
<td class="inv-item items" style="text-align: left; color: #040405; padding-left: 40px">{{$item->price/100}}</td>
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 40px">{{$item->price/100}}</td>
|
||||||
@if($estimate->discount_per_item === 'YES')
|
@if($estimate->discount_per_item === 'YES')
|
||||||
<td class="inv-item items" style="text-align: left; color: #040405; padding-left: 10px">
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-left: 10px">
|
||||||
@if($item->discount_type === 'fixed')
|
@if($item->discount_type === 'fixed')
|
||||||
{{$item->discount_val/100}}
|
{{$item->discount_val/100}}
|
||||||
@endif
|
@endif
|
||||||
@ -30,12 +35,15 @@
|
|||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
@endif
|
@endif
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405">{{$item->total/100}}</td>
|
<td class="inv-item items" style="text-align: right; color: #040405;">{{$item->total/100}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@php
|
||||||
|
$index += 1
|
||||||
|
@endphp
|
||||||
@endforeach
|
@endforeach
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<table width="100%" style="margin-left:420px" cellspacing="0px" border="0" class="table3">
|
<table width="100%" cellspacing="0px" style="margin-left:420px" border="0" class="table3 @if(count($estimate->items) > 12) page-break @endif">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="no-borde" style="color: #55547A; padding-left:10px; font-size:12px;">Subtotal</td>
|
<td class="no-borde" style="color: #55547A; padding-left:10px; font-size:12px;">Subtotal</td>
|
||||||
<td class="no-border items"
|
<td class="no-border items"
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
html {
|
html {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
@ -35,7 +36,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 90px;
|
height: 90px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
top: 0px;
|
top: -50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-logo {
|
.header-logo {
|
||||||
@ -71,7 +72,7 @@
|
|||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
display: block;
|
display: block;
|
||||||
padding-top: 60px;
|
padding-top: 16px;
|
||||||
padding-bottom: 60px;
|
padding-bottom: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,6 +252,7 @@
|
|||||||
page-break-after: auto;
|
page-break-after: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.table2 hr {
|
.table2 hr {
|
||||||
height:0.1px;
|
height:0.1px;
|
||||||
}
|
}
|
||||||
@ -263,7 +265,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr.main-table-header th {
|
tr.main-table-header th {
|
||||||
border-bottom: 1px solid #EAF1FB;
|
border-bottom: 0.620315px solid #E8E8E8;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -380,8 +382,8 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<hr class="header-line" style="border: 0.620315px solid #E8E8E8;"/>
|
||||||
</div>
|
</div>
|
||||||
<hr class="header-line" />
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="address">
|
<div class="address">
|
||||||
<div class="company">
|
<div class="company">
|
||||||
|
|||||||
@ -264,7 +264,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr.main-table-header th {
|
tr.main-table-header th {
|
||||||
border-bottom: 1px solid #EAF1FB;
|
border-bottom: 0.620315px solid #E8E8E8;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
<div class="notes">
|
@if ($invoice->notes != '' && $invoice->notes != null)
|
||||||
<div class="notes-label">
|
<div class="notes">
|
||||||
Notes
|
<div class="notes-label">
|
||||||
|
Notes
|
||||||
|
</div>
|
||||||
|
{{$invoice->notes}}
|
||||||
</div>
|
</div>
|
||||||
{{$invoice->notes}}
|
@endif
|
||||||
</div>
|
|
||||||
|
|||||||
@ -1,27 +1,32 @@
|
|||||||
<table width="100%" class="table2" cellspacing="0" border="0">
|
<table width="100%" class="table2" cellspacing="0" border="0">
|
||||||
<tr class="main-table-header">
|
<tr class="main-table-header">
|
||||||
|
<th class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">#</th>
|
||||||
@if($invoice->discount_per_item === 'NO')
|
@if($invoice->discount_per_item === 'NO')
|
||||||
<th width="80%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
|
<th width="80%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
|
||||||
@else
|
@else
|
||||||
<th width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
|
<th width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
|
||||||
@endif
|
@endif
|
||||||
<th width="17%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Quantity</th>
|
<th width="17%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Quantity</th>
|
||||||
<th width="18%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 40px">Price</th>
|
<th width="18%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 40px">Price</th>
|
||||||
@if($invoice->discount_per_item === 'YES')
|
@if($invoice->discount_per_item === 'YES')
|
||||||
<th width="10%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 10px">Discount</th>
|
<th width="10%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-left: 10px">Discount</th>
|
||||||
@endif
|
@endif
|
||||||
<th width="15%" class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</th>
|
<th width="15%" class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@php
|
||||||
|
$index = 1
|
||||||
|
@endphp
|
||||||
@foreach ($invoice->items as $item)
|
@foreach ($invoice->items as $item)
|
||||||
<tr class="item-details">
|
<tr class="item-details">
|
||||||
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px; vertical-align: top;">{{$index}}</td>
|
||||||
<td class="inv-item items" style="text-align: left; color: #040405;padding-left: 0px">
|
<td class="inv-item items" style="text-align: left; color: #040405;padding-left: 0px">
|
||||||
<span>{{ $item->name }}</span><br>
|
<span>{{ $item->name }}</span><br>
|
||||||
<span style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{{ $item->description }}</span>
|
<span style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{{ $item->description }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px">{{$item->quantity}}</td>
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px">{{$item->quantity}}</td>
|
||||||
<td class="inv-item items" style="text-align: left; color: #040405; padding-left: 40px">{{$item->price/100}}</td>
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-right: 40px">{{$item->price/100}}</td>
|
||||||
@if($invoice->discount_per_item === 'YES')
|
@if($invoice->discount_per_item === 'YES')
|
||||||
<td class="inv-item items" style="text-align: left; color: #040405; padding-left: 10px">
|
<td class="inv-item items" style="text-align: right; color: #040405; padding-left: 10px">
|
||||||
@if($item->discount_type === 'fixed')
|
@if($item->discount_type === 'fixed')
|
||||||
{{$item->discount_val/100}}
|
{{$item->discount_val/100}}
|
||||||
@endif
|
@endif
|
||||||
@ -30,8 +35,11 @@
|
|||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
@endif
|
@endif
|
||||||
<td class="inv-item items" style="text-align: right; color: #040405">{{$item->total/100}}</td>
|
<td class="inv-item items" style="text-align: right; color: #040405;">{{$item->total/100}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@php
|
||||||
|
$index += 1
|
||||||
|
@endphp
|
||||||
@endforeach
|
@endforeach
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user