fix conflict

This commit is contained in:
Mohit Panjwani
2019-11-12 18:41:25 +05:30
40 changed files with 2102 additions and 377 deletions

View File

@ -79,7 +79,7 @@ class ItemsController extends Controller
foreach ($request->taxes as $tax) {
$item->taxes()->updateOrCreate(
['tax_type_id' => $tax['tax_type_id']],
['amount' => $tax['amount'], 'percent' => $tax['percent'], 'percent' => $tax['name']]
['amount' => $tax['amount'], 'percent' => $tax['percent'], 'name' => $tax['name']]
);
}
}

View File

@ -18173,6 +18173,7 @@ fieldset[disabled] .multiselect {
.reports .report-view-button {
display: none;
color: #fff;
}
.reports .report-fields-container {
@ -18208,8 +18209,13 @@ fieldset[disabled] .multiselect {
display: none;
}
.reports .report-submit-button-container {
display: none;
}
.reports .report-view-button {
display: flex;
color: #fff !important;
justify-content: center;
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -35,6 +35,8 @@
<div v-if="$v.formData.price.$error">
<span v-if="!$v.formData.price.required" class="text-danger">{{ $tc('validation.required') }}</span>
<span v-if="!$v.formData.price.numeric" class="text-danger">{{ $tc('validation.numbers_only') }}</span>
<span v-if="!$v.formData.price.maxLength" class="text-danger">{{ $t('validation.price_maxlength') }}</span>
<span v-if="!$v.formData.price.minValue" class="text-danger">{{ $t('validation.price_minvalue') }}</span>
</div>
</div>
</div>
@ -138,7 +140,8 @@ export default {
price: {
required,
numeric,
minValue: minValue(0.1)
minValue: minValue(0.1),
maxLength: maxLength(10)
},
description: {
maxLength: maxLength(255)

View File

@ -9,6 +9,7 @@
<script>
import Chart from 'chart.js'
import Utils from '../../helpers/utilities'
import { mapGetters } from 'vuex'
export default {
props: {
@ -46,9 +47,20 @@ export default {
type: Function,
require: false,
default: Function
},
FormatGraphMoney: {
type: Function,
require: false,
default: Function
}
},
computed: {
...mapGetters('currency', [
'defaultCurrency'
])
},
watch: {
labels (val) {
this.update()
@ -56,6 +68,7 @@ export default {
},
mounted () {
let self = this
let context = this.$refs.graph.getContext('2d')
let options = {
responsive: true,
@ -64,7 +77,7 @@ export default {
enabled: true,
callbacks: {
label: function (tooltipItem, data) {
return Utils.formatGraphMoney(tooltipItem.value)
return self.FormatGraphMoney(tooltipItem.value, self.defaultCurrency)
}
}
},

View File

@ -549,6 +549,16 @@ export default {
action: 'Action',
add_currency: 'Add Currency'
},
mail: {
host: 'Mail Host',
port: 'Mail Port',
driver: 'Mail Driver',
password: 'Mail Password',
username: 'Mail Username',
mail_config: 'Mail Configuration',
encryption: 'Mail Encryption',
mail_config_desc: 'Below details will be used to update the mail environment. Also you can change the details anytime after logging in.'
},
pdf: {
title: 'PDF Setting',
footer_text: 'Footer Text',
@ -680,6 +690,7 @@ export default {
username: 'Username',
next: 'Next',
continue: 'Continue',
skip: 'Skip',
database: {
database: 'Site URL & Database',
connection: 'Database Connection',
@ -750,7 +761,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',
amount_maxlength: 'Amount should not be greater than 10 digits.',
amount_minvalue: 'Amount should be greater than 0 digits',
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

@ -224,6 +224,7 @@ export default {
action: 'Acción',
notes: 'Notas',
tax: 'Impuesto',
send_estimate: 'Enviar presupuesto',
estimate_template: 'Plantilla de estimación',
convert_to_invoice: 'Convertir a factura',
mark_as_sent: 'Marcar como enviado',
@ -548,7 +549,7 @@ export default {
right: 'Derecho',
left: 'Izquierda',
action: 'Acción',
add_currency: 'Agregar moneda',
add_currency: 'Agregar moneda'
},
pdf: {
title: 'Configuración de PDF',
@ -595,8 +596,6 @@ export default {
estimate_viewed_desc: 'Cuando su cliente ve la estimación enviada a través del panel de control del cráter.',
save: 'Salvar',
email_save_message: 'Correo electrónico guardado con éxito',
invoice_viewed_message: 'Factura vista',
estimate_viewed_message: 'Estimación vista',
please_enter_email: 'Por favor, introduzca su correo electrónico'
},
tax_types: {
@ -641,7 +640,6 @@ export default {
preference: 'Preferencia | Preferencias',
general_settings: 'Preferencias predeterminadas para el sistema.',
updated_message: 'Preferencias actualizadas exitosamente',
set_discount_per_item_message: 'Descuento establecido por artículo',
select_language: 'seleccione el idioma',
select_time_zone: 'selecciona la zona horaria',
select_date_formate: 'seleccione formato de fecha',
@ -667,7 +665,7 @@ export default {
state: 'Estado',
city: 'Ciudad',
address: 'Habla a',
street: 'Calle1 '| 'Calle # 2',
street: 'Calle1 ' | 'Calle # 2',
phone: 'Teléfono',
zip_code: 'Código postal',
go_back: 'Regresa',
@ -675,7 +673,52 @@ export default {
language: 'Idioma',
time_zone: 'Zona horaria',
fiscal_year: 'Año financiero',
date_format: 'Formato de fecha'
date_format: 'Formato de fecha',
from_address: 'De la Dirección',
username: 'Nombre de usuario',
next: 'Próximo',
continue: 'Hacer continuación',
database: {
database: 'URL del sitio y base de datose',
connection: 'Conexión de base de datos',
host: 'Database Host',
port: 'Host de base de datos',
password: 'Contraseña de base de datos',
app_url: 'URL de la aplicación',
username: 'Nombre de usuario de la base de datos',
db_name: 'Nombre de la base de datos',
desc: 'Cree una base de datos en su servidor y establezca las credenciales utilizando el siguiente formulario.'
},
permissions: {
permissions: 'Permisos',
permission_desc: 'A continuación se muestra la lista de permisos de carpeta necesarios para que la aplicación funcione. Si la verificación de permisos falla, asegúrese de actualizar los permisos de su carpeta.'
},
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.'
},
req: {
system_req: 'Requisitos del sistema',
php_req_version: 'Php (versión {version} necesario)',
check_req: 'Consultar requisitos',
system_req_desc: 'Crater tiene algunos requisitos de servidor. Asegúrese de que su servidor tenga la versión de php requerida y todas las extensiones mencionadas a continuación.'
},
errors: {
migrate_failed: 'La migración falló',
database_variables_save_error: 'No se puede conectar a la base de datos con los valores proporcionados.',
mail_variables_save_error: 'La configuración del correo electrónico ha fallado.',
connection_failed: 'Conexión de base de datos fallida'
},
success: {
mail_variables_save_successfully: 'Correo electrónico configurado correctamente',
database_variables_save_successfully: 'Base de datos configurada con éxito.'
}
},
layout_login: {
copyright_crater: 'Copyright @ Crater - 2019',
@ -706,7 +749,9 @@ export default {
payment_greater_than_due_amount: 'El pago ingresado es mayor al monto adeudado de esta factura.',
quantity_maxlength: 'La cantidad no debe ser mayor de 10 dígitos.',
price_maxlength: 'El precio no debe ser mayor de 10 dígitos.',
price_minvalue: 'El precio debe ser mayor que 0 dígitos',
amount_maxlength: 'La cantidad no debe ser mayor de 10 dígitos.',
amount_minvalue: 'La cantidad debe ser mayor que 0 dígitos',
description_maxlength: 'La descripción no debe tener más de 255 caracteres.',
maximum_options_error: 'Máximo de {max} opciones seleccionadas. Primero elimine una opción seleccionada para seleccionar otra.',
notes_maxlength: 'Las notas no deben tener más de 255 caracteres.',

View File

@ -667,7 +667,7 @@ export default {
state: 'Etat',
city: 'Ville',
address: 'Adresse',
street: 'Street1 '| 'Rue # 2',
street: 'Street1 ' | 'Rue # 2',
phone: 'Téléphone',
zip_code: 'Code postal',
go_back: 'Retourner',
@ -675,7 +675,52 @@ export default {
language: 'La langue',
time_zone: 'Fuseau horaire',
fiscal_year: 'Année financière',
date_format: 'Format de date'
date_format: 'Format de date',
from_address: "De l'adresse",
username: "Nom d'utilisateur",
next: 'Suivant',
continue: 'Continuer',
database: {
database: 'URL du site et base de données',
connection: 'Connexion à la base de données',
host: 'Hôte de base de données',
port: 'Port de base de données',
password: 'Mot de passe de base de données',
app_url: 'Application URL',
username: "Nom d'utilisateur de la base de données",
db_name: 'Nom de la base de données',
desc: "Créez une base de données sur votre serveur et définissez les informations d'identification à l'aide du formulaire ci-dessous."
},
permissions: {
permissions: 'Les permissions',
permission_desc: "Vous trouverez ci-dessous la liste des autorisations de dossier requises pour le fonctionnement de l'application. Si la vérification des autorisations échoue, veillez à mettre à jour vos autorisations de dossier."
},
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."
},
req: {
system_req: 'Configuration requise',
php_req_version: 'Php (version {version} nécessaire)',
check_req: 'Vérifier les exigences',
system_req_desc: 'Crater a quelques exigences de serveur. Assurez-vous que votre serveur dispose de la version PHP requise et de toutes les extensions mentionnées ci-dessous.'
},
errors: {
migrate_failed: 'Migration impossible',
database_variables_save_error: 'Impossible de se connecter à la base de données avec les valeurs fournies.',
mail_variables_save_error: 'La configuration du courrier électronique a échoué.',
connection_failed: 'La connexion à la base de données a échoué'
},
success: {
mail_variables_save_successfully: 'Email configuré avec succès',
database_variables_save_successfully: 'Base de données configurée avec succès.'
}
},
layout_login: {
copyright_crater: 'Copyright @ Crater - 2019',
@ -706,7 +751,9 @@ export default {
payment_greater_than_due_amount: 'Le paiement entré est plus que le montant dû de cette facture.',
quantity_maxlength: 'La quantité ne doit pas dépasser 10 chiffres.',
price_maxlength: 'Le prix ne doit pas dépasser 10 chiffres.',
price_minvalue: 'Le prix doit être supérieur à 0 chiffre',
amount_maxlength: 'Le montant ne doit pas dépasser 10 chiffres.',
amount_minvalue: 'Le montant doit être supérieur à 0 chiffre',
description_maxlength: 'La description ne doit pas dépasser 255 caractères.',
maximum_options_error: 'Maximum de {max} options sélectionnées. Commencez par supprimer une option sélectionnée pour en sélectionner une autre.',
notes_maxlength: 'Les notes ne doivent pas dépasser 255 caractères.',

View File

@ -71,6 +71,7 @@ import Preferences from './views/settings/Preferences.vue'
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 Wizard from './views/wizard/Index.vue'
@ -327,6 +328,11 @@ const routes = [
name: 'expense.category',
component: ExpenseCategory
},
{
path: 'mail-configuration',
name: 'mailconfig',
component: MailConfig
},
{
path: 'notifications',
name: 'notifications',

View File

@ -130,7 +130,7 @@ export const markAsRejected = ({ commit, dispatch, state }, data) => {
export const markAsSent = ({ commit, dispatch, state }, data) => {
return new Promise((resolve, reject) => {
window.axios.post(`/api/estimates/sent`, data).then((response) => {
window.axios.post(`/api/estimates/mark-as-sent`, data).then((response) => {
// commit(types.UPDATE_INVOICE, response.data)
resolve(response)
}).catch((err) => {

View File

@ -96,6 +96,7 @@
<line-chart
v-if="isLoaded"
:format-money="$utils.formatMoney"
:format-graph-money="$utils.formatGraphMoney"
:invoices="getChartInvoices"
:expenses="getChartExpenses"
:receipts="getReceiptTotals"

View File

@ -688,7 +688,7 @@ export default {
isValid = false
}
})
if (this.$v.newEstimate.$invalid === false && isValid === true) {
if (!this.$v.selectedCustomer.$invalid && this.$v.newEstimate.$invalid === false && isValid === true) {
return true
}
return false

View File

@ -28,6 +28,7 @@
@select="onSelectItem"
@deselect="deselectItem"
@onDesriptionInput="$v.item.description.$touch()"
@onSelectItem="isSelected = true"
/>
</div>
</td>
@ -193,13 +194,17 @@ export default {
prefix: '$ ',
precision: 2,
masked: false
}
},
isSelected: false
}
},
computed: {
...mapGetters('item', [
'items'
]),
...mapGetters('modal', [
'modalActive'
]),
...mapGetters('currency', [
'defaultCurrencyForInput'
]),
@ -284,6 +289,11 @@ export default {
if (this.item.discount_type === 'percentage') {
this.item.discount_val = (this.item.discount * newValue) / 100
}
},
modalActive (val) {
if (!val) {
this.isSelected = false
}
}
},
validations () {
@ -313,7 +323,11 @@ export default {
},
created () {
window.hub.$on('checkItems', this.validateItem)
window.hub.$on('newItem', this.onSelectItem)
window.hub.$on('newItem', (val) => {
if (!this.item.item_id && this.modalActive && this.isSelected) {
this.onSelectItem(val)
}
})
},
methods: {
updateTax (data) {

View File

@ -126,6 +126,7 @@ export default {
this.$emit('search', val)
},
openItemModal () {
this.$emit('onSelectItem')
this.openModal({
'title': 'Add Item',
'componentName': 'ItemModal'

View File

@ -92,13 +92,14 @@
<money
v-model="amount"
v-bind="defaultCurrencyForInput"
:class="{'invalid' : $v.formData.amount.$error}"
class="input-field"
@input="$v.formData.amount.$touch()"
/>
</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.maxLength" class="text-danger">{{ $t('validation.amount_maxlength') }}</span>
<span v-if="!$v.formData.amount.maxValue" class="text-danger">{{ $t('validation.amount_minvalue') }}</span>
</div>
</div>
<div class="form-group col-sm-6">

View File

@ -519,14 +519,6 @@ export default {
...mapActions('item', [
'fetchItems'
]),
isEmpty (obj) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
return false
}
}
return true
},
selectFixed () {
if (this.newInvoice.discount_type === 'fixed') {
return

View File

@ -28,6 +28,7 @@
@select="onSelectItem"
@deselect="deselectItem"
@onDesriptionInput="$v.item.description.$touch()"
@onSelectItem="isSelected = true"
/>
</div>
</td>
@ -194,13 +195,17 @@ export default {
prefix: '$ ',
precision: 2,
masked: false
}
},
isSelected: false
}
},
computed: {
...mapGetters('item', [
'items'
]),
...mapGetters('modal', [
'modalActive'
]),
...mapGetters('currency', [
'defaultCurrencyForInput'
]),
@ -285,6 +290,11 @@ export default {
if (this.item.discount_type === 'percentage') {
this.item.discount_val = (this.item.discount * newValue) / 100
}
},
modalActive (val) {
if (!val) {
this.isSelected = false
}
}
},
validations () {
@ -314,7 +324,11 @@ export default {
},
created () {
window.hub.$on('checkItems', this.validateItem)
window.hub.$on('newItem', this.onSelectItem)
window.hub.$on('newItem', (val) => {
if (!this.item.item_id && this.modalActive && this.isSelected) {
this.onSelectItem(val)
}
})
},
methods: {
updateTax (data) {

View File

@ -115,6 +115,7 @@ export default {
this.$emit('search', val)
},
openItemModal () {
this.$emit('onSelectItem')
this.openModal({
'title': 'Add Item',
'componentName': 'ItemModal'

View File

@ -34,16 +34,16 @@
<label>{{ $t('items.price') }}</label><span class="text-danger"> *</span>
<div class="base-input">
<money
:invalid="$v.formData.price.$error"
:class="{'invalid' : $v.formData.price.$error}"
v-model="price"
v-bind="defaultCurrencyForInput"
class="input-field"
@input="$v.formData.price.$touch()"
/>
</div>
<div v-if="$v.formData.price.$error">
<span v-if="!$v.formData.price.required" class="text-danger">{{ $t('validation.required') }} </span>
<span v-if="!$v.formData.price.maxLength" class="text-danger">{{ $t('validation.price_maxlength') }}</span>
<span v-if="!$v.formData.price.minValue" class="text-danger">{{ $t('validation.price_minvalue') }}</span>
</div>
</div>
<div class="form-group">
@ -92,7 +92,8 @@
<script>
import { validationMixin } from 'vuelidate'
import { mapActions, mapGetters } from 'vuex'
const { required, minLength, numeric, alpha, minValue, maxLength} = require('vuelidate/lib/validators')
const { required, minLength, numeric, alpha, minValue, maxLength } = require('vuelidate/lib/validators')
export default {
mixins: {
validationMixin

View File

@ -48,7 +48,7 @@
</div>
<div class="col-sm-8 reports-tab-container">
<iframe :src="getReportUrl" class="reports-frame-style"/>
<a :href="getReportUrl" class="base-button btn btn-primary btn-lg report-view-button" target="_blank">
<a class="base-button btn btn-primary btn-lg report-view-button" @click="viewReportsPDF">
<font-awesome-icon icon="file-pdf" class="vue-icon icon-left svg-inline--fa fa-download fa-w-16 mr-2" /> <span>{{ $t('reports.view_pdf') }}</span>
</a>
</div>
@ -179,6 +179,11 @@ export default {
setRangeToCustom () {
this.selectedRange = 'Custom'
},
async viewReportsPDF () {
let data = await this.getReports()
window.open(this.getReportUrl, '_blank')
return data
},
async getReports (isDownload = false) {
this.$v.range.$touch()
this.$v.formData.$touch()

View File

@ -48,7 +48,7 @@
</div>
<div class="col-sm-8 reports-tab-container">
<iframe :src="getReportUrl" class="reports-frame-style"/>
<a :href="getReportUrl" class="base-button btn btn-primary btn-lg report-view-button" target="_blank">
<a class="base-button btn btn-primary btn-lg report-view-button" @click="viewReportsPDF">
<font-awesome-icon icon="file-pdf" class="vue-icon icon-left svg-inline--fa fa-download fa-w-16 mr-2" /> <span>{{ $t('reports.view_pdf') }}</span>
</a>
</div>
@ -184,6 +184,11 @@ export default {
setRangeToCustom () {
this.selectedRange = 'Custom'
},
async viewReportsPDF () {
let data = await this.getReports()
window.open(this.getReportUrl, '_blank')
return data
},
async getReports (isDownload = false) {
this.$v.range.$touch()
this.$v.formData.$touch()

View File

@ -70,7 +70,7 @@
</div>
<div class="col-sm-8 reports-tab-container">
<iframe :src="getReportUrl" class="reports-frame-style"/>
<a :href="getReportUrl" class="base-button btn btn-primary btn-lg report-view-button" target="_blank">
<a class="base-button btn btn-primary btn-lg report-view-button" @click="viewReportsPDF">
<font-awesome-icon icon="file-pdf" class="vue-icon icon-left svg-inline--fa fa-download fa-w-16 mr-2" /> <span>{{ $t('reports.view_pdf') }}</span>
</a>
</div>
@ -217,6 +217,11 @@ export default {
this.url = `${this.itemsSiteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
return true
},
async viewReportsPDF () {
let data = await this.getReports()
window.open(this.getReportUrl, '_blank')
return data
},
async getReports (isDownload = false) {
this.$v.range.$touch()
this.$v.formData.$touch()

View File

@ -48,7 +48,7 @@
</div>
<div class="col-sm-8 reports-tab-container">
<iframe :src="getReportUrl" class="reports-frame-style"/>
<a :href="getReportUrl" class="base-button btn btn-primary btn-lg report-view-button" target="_blank">
<a class="base-button btn btn-primary btn-lg report-view-button" @click="viewReportsPDF">
<font-awesome-icon icon="file-pdf" class="vue-icon icon-left svg-inline--fa fa-download fa-w-16 mr-2" /> <span>{{ $t('reports.view_pdf') }}</span>
</a>
</div>
@ -179,6 +179,11 @@ export default {
setRangeToCustom () {
this.selectedRange = 'Custom'
},
async viewReportsPDF () {
let data = await this.getReports()
window.open(this.getReportUrl, '_blank')
return data
},
async getReports (isDownload = false) {
this.$v.range.$touch()
this.$v.formData.$touch()

View File

@ -0,0 +1,213 @@
<template>
<div class="setting-main-container">
<div class="card setting-card">
<div class="page-header">
<h3 class="page-title">{{ $t('settings.mail.mail_config') }}</h3>
<p class="page-sub-title">
{{ $t('settings.mail.mail_config_desc') }}
</p>
</div>
<form action="" @submit.prevent="saveEmailConfig()">
<div class="row my-2 mt-5">
<div class="col-md-6 my-2">
<label class="form-label">{{ $t('settings.mail.driver') }}</label>
<span class="text-danger"> *</span>
<base-select
v-model="mailConfigData.mail_driver"
:invalid="$v.mailConfigData.mail_driver.$error"
:options="mail_drivers"
:searchable="true"
:show-labels="false"
@change="$v.mailConfigData.mail_driver.$touch()"
/>
<div v-if="$v.mailConfigData.mail_driver.$error">
<span v-if="!$v.mailConfigData.mail_driver.required" class="text-danger">
{{ $tc('validation.required') }}
</span>
</div>
</div>
<div class="col-md-6 my-2">
<label class="form-label">{{ $t('settings.mail.host') }}</label>
<span class="text-danger"> *</span>
<base-input
:invalid="$v.mailConfigData.mail_host.$error"
v-model.trim="mailConfigData.mail_host"
type="text"
name="mail_host"
@input="$v.mailConfigData.mail_host.$touch()"
/>
<div v-if="$v.mailConfigData.mail_host.$error">
<span v-if="!$v.mailConfigData.mail_host.required" class="text-danger">
{{ $tc('validation.required') }}
</span>
</div>
</div>
</div>
<div class="row my-2">
<div class="col-md-6 my-2">
<label class="form-label">{{ $t('settings.mail.username') }}</label>
<span class="text-danger"> *</span>
<base-input
:invalid="$v.mailConfigData.mail_username.$error"
v-model.trim="mailConfigData.mail_username"
type="text"
name="db_name"
@input="$v.mailConfigData.mail_username.$touch()"
/>
<div v-if="$v.mailConfigData.mail_username.$error">
<span v-if="!$v.mailConfigData.mail_username.required" class="text-danger">
{{ $tc('validation.required') }}
</span>
</div>
</div>
<div class="col-md-6 my-2">
<label class="form-label">{{ $t('settings.mail.password') }}</label>
<span class="text-danger"> *</span>
<base-input
:invalid="$v.mailConfigData.mail_password.$error"
v-model.trim="mailConfigData.mail_password"
type="mail_password"
name="name"
@input="$v.mailConfigData.mail_password.$touch()"
/>
<div v-if="$v.mailConfigData.mail_password.$error">
<span v-if="!$v.mailConfigData.mail_password.required" class="text-danger">
{{ $tc('validation.required') }}
</span>
</div>
</div>
</div>
<div class="row my-2">
<div class="col-md-6 my-2">
<label class="form-label">{{ $t('settings.mail.port') }}</label>
<span class="text-danger"> *</span>
<base-input
:invalid="$v.mailConfigData.mail_port.$error"
v-model.trim="mailConfigData.mail_port"
type="text"
name="mail_port"
@input="$v.mailConfigData.mail_port.$touch()"
/>
<div v-if="$v.mailConfigData.mail_port.$error">
<span v-if="!$v.mailConfigData.mail_port.required" class="text-danger">
{{ $tc('validation.required') }}
</span>
<span v-if="!$v.mailConfigData.mail_port.numeric" class="text-danger">
{{ $tc('validation.numbers_only') }}
</span>
</div>
</div>
<div class="col-md-6 my-2">
<label class="form-label">{{ $t('settings.mail.encryption') }}</label>
<span class="text-danger"> *</span>
<base-input
:invalid="$v.mailConfigData.mail_encryption.$error"
v-model.trim="mailConfigData.mail_encryption"
type="text"
name="name"
@input="$v.mailConfigData.mail_encryption.$touch()"
/>
<div v-if="$v.mailConfigData.mail_encryption.$error">
<span v-if="!$v.mailConfigData.mail_encryption.required" class="text-danger">
{{ $tc('validation.required') }}
</span>
</div>
</div>
</div>
<base-button
:loading="loading"
class="pull-right mt-5"
icon="save"
color="theme"
type="submit"
>
{{ $t('wizard.save_cont') }}
</base-button>
</form>
</div>
</div>
</template>
<script>
import MultiSelect from 'vue-multiselect'
import { validationMixin } from 'vuelidate'
import Ls from '../../services/ls'
const { required, email, numeric } = require('vuelidate/lib/validators')
export default {
components: {
MultiSelect
},
mixins: [validationMixin],
data () {
return {
mailConfigData: {
mail_driver: 'smtp',
mail_host: 'mailtrap.io',
mail_port: 2525,
mail_username: 'cc3c64516febd4',
mail_password: 'e6a0176301f587',
mail_encryption: 'tls'
},
loading: false,
mail_drivers: []
}
},
validations: {
mailConfigData: {
mail_driver: {
required
},
mail_host: {
required
},
mail_port: {
required,
numeric
},
mail_username: {
required
},
mail_password: {
required
},
mail_encryption: {
required
}
}
},
mounted () {
// this.getMailDrivers()
},
methods: {
async getMailDrivers () {
this.loading = true
let response = await window.axios.get('/api/admin/onboarding/environment/mail')
if (response.data) {
this.mail_drivers = response.data
this.loading = false
}
},
async saveEmailConfig () {
this.$v.mailConfigData.$touch()
if (this.$v.mailConfigData.$invalid) {
return true
}
this.loading = true
try {
let response = await window.axios.post('/api/admin/onboarding/environment/mail', this.mailConfigData)
if (response.data.success) {
window.toastr['success'](this.$t('wizard.success.' + response.data.success))
} else {
window.toastr['error'](this.$t('wizard.errors.' + response.data.error))
}
this.loading = false
return true
} catch (e) {
window.toastr['error']('Something went wrong')
}
}
}
}
</script>

View File

@ -113,7 +113,11 @@
<h3 class="page-title">{{ $t('settings.preferences.discount_setting') }}</h3>
<div class="flex-box">
<div class="left">
<base-switch v-model="discount_per_item" class="btn-switch" @change="setDiscount" />
<base-switch
v-model="discount_per_item"
class="btn-switch"
@change="setDiscount"
/>
</div>
<div class="right ml-15">
<p class="box-title"> {{ $t('settings.preferences.discount_per_item') }} </p>

View File

@ -63,6 +63,12 @@ export default {
icon: 'list-alt',
iconType: 'far'
},
{
link: '/admin/settings/mail-configuration',
title: 'settings.mail.mail_config',
icon: 'envelope',
iconType: 'fa'
},
{
link: '/admin/settings/notifications',
title: 'settings.menu_title.notifications',

View File

@ -109,15 +109,26 @@
</div>
</div>
</div>
<base-button
:loading="loading"
class="pull-right mt-5"
icon="save"
color="theme"
type="submit"
>
{{ $t('wizard.save_cont') }}
</base-button>
<div class="row mt-5">
<base-button
:loading="loading"
class="pull-right"
icon="save"
color="theme"
type="submit"
>
{{ $t('wizard.save_cont') }}
</base-button>
<base-button
:loading="loading"
class="pull-right ml-4"
outline
color="theme"
@click="$emit('next')"
>
{{ $t('wizard.skip') }}
</base-button>
</div>
</form>
</div>
</template>
@ -137,10 +148,10 @@ export default {
mailConfigData: {
mail_driver: 'smtp',
mail_host: 'mailtrap.io',
mail_port: 2525,
mail_username: 'cc3c64516febd4',
mail_password: 'e6a0176301f587',
mail_encryption: 'tls'
mail_port: null,
mail_username: null,
mail_password: null,
mail_encryption: null
},
loading: false,
mail_drivers: []

View File

@ -21,6 +21,7 @@
.report-view-button {
display: none;
color: $btn-secondary-color;
}
.report-fields-container {
@ -61,8 +62,13 @@
display: none;
}
.report-submit-button-container {
display: none;
}
.report-view-button {
display: flex;
color: $btn-secondary-color !important;
justify-content: center
}

View File

@ -72,6 +72,7 @@
.wrapper {
display: block;
padding-top: 60px;
padding-bottom: 60px;
}
.address {
@ -244,6 +245,8 @@
margin-top: 35px;
border-bottom: 1px solid #EAF1FB;
padding: 0px 30px 0 30px;
page-break-before: avoid;
page-break-after: auto;
}
.table2 hr {
@ -257,7 +260,7 @@
padding: 5px;
}
tr.main-table-header td {
tr.main-table-header th {
border-bottom: 1px solid #EAF1FB;
font-style: normal;
font-weight: normal;
@ -284,28 +287,33 @@
padding-bottom: 8px;
}
.padd2 {
padding-top: 2px;
padding-bottom: 2px;
}
.table3 {
border: 1px solid #EAF1FB;
border-top: none;
padding-right: 30px;
box-sizing: border-box;
width: 230px;
height: 100px;
position: absolute;
right: -25;
width: 630px;
page-break-inside: avoid;
page-break-before: auto;
page-break-after: auto;
}
.text-per-item-table3 {
border: 1px solid #EAF1FB;
border-top: none;
padding-right: 30px;
box-sizing: border-box;
width: 260px;
/* height: 100px; */
position: absolute;
right: -25;
.total-border-left {
border: 1px solid #E8E8E8!important;
border-right: 0px !important;
padding-top: 0px;
padding:8px !important;
}
.total-border-right {
border: 1px solid #E8E8E8!important;
border-left: 0px !important;
padding-top: 0px;
padding:8px !important;
}
.inv-item {
border-color: #d9d9d9;
}
@ -323,6 +331,30 @@
color:rgba(0, 0, 0, 0.85);
}
.notes {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: 300;
font-size: 12px;
color: #595959;
margin-top: 15px;
margin-left: 30px;
width: 442px;
text-align: left;
}
.notes-label {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: normal;
font-size: 15px;
line-height: 22px;
letter-spacing: 0.05em;
color: #040405;
width: 108px;
height: 19.87px;
padding-bottom: 10px;
}
</style>
</head>
@ -380,6 +412,7 @@
<div style="clear: both;"></div>
</div>
@include('app.pdf.estimate.partials.table')
@include('app.pdf.estimate.partials.notes')
</div>
</body>
</html>

View File

@ -74,6 +74,7 @@
.wrapper {
display: block;
padding-top: 110px;
padding-bottom: 60px;
}
.address {
@ -245,6 +246,8 @@
margin-top: 200px;
border-bottom: 1px solid #EAF1FB;
padding: 0px 30px 0 30px;
page-break-before: avoid;
page-break-after: auto;
}
.table2 hr {
@ -258,7 +261,7 @@
padding: 5px;
}
tr.main-table-header td {
tr.main-table-header th {
border-bottom: 1px solid #EAF1FB;
font-style: normal;
font-weight: normal;
@ -295,27 +298,21 @@
padding-bottom: 8px;
}
.padd2 {
padding-top: 2px;
padding-bottom: 2px;
}
.table3 {
border: 1px solid #EAF1FB;
border-top: none;
padding-right: 30px;
box-sizing: border-box;
width: 230px;
height: 100px;
position: absolute;
right: -25;
width: 630px;
page-break-inside: avoid;
page-break-before: auto;
page-break-after: auto;
}
.text-per-item-table3 {
border: 1px solid #EAF1FB;
border-top: none;
padding-right: 30px;
box-sizing: border-box;
width: 260px;
/* height: 100px; */
position: absolute;
right: -25;
}
.inv-item {
border-color: #d9d9d9;
@ -361,6 +358,32 @@
margin-bottom:1px;
margin-top:0;
}
.notes {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: 300;
font-size: 12px;
color: #595959;
margin-top: 15px;
margin-left: 30px;
width: 442px;
text-align: left;
}
.notes-label {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: normal;
font-size: 15px;
line-height: 22px;
letter-spacing: 0.05em;
color: #040405;
width: 108px;
height: 19.87px;
padding-bottom: 10px;
}
</style>
</head>
<body>
@ -402,6 +425,7 @@
</div>
</div>
@include('app.pdf.estimate.partials.table')
@include('app.pdf.estimate.partials.notes')
</div>
</body>
</html>

View File

@ -80,6 +80,7 @@
.wrapper {
display: block;
padding-top: 110px;
padding-bottom: 60px;
}
.address {
@ -233,7 +234,7 @@
.main-table-header {
border-bottom: 1px solid red;
}
tr.main-table-header td {
tr.main-table-header th {
font-style: normal;
font-weight: 600;
font-size: 12px;
@ -249,6 +250,8 @@
margin-top: 188px;
border-bottom: 1px solid #EAF1FB;
padding: 0px 30px 0 30px;
page-break-before: avoid;
page-break-after: auto;
}
.table2 hr {
@ -284,26 +287,19 @@
padding-bottom: 8px;
}
.table3 {
border: 1px solid #EAF1FB;
border-top: none;
padding-right: 30px;
box-sizing: border-box;
width: 230px;
height: 100px;
position: absolute;
right: -25;
.padd2 {
padding-top: 2px;
padding-bottom: 2px;
}
.text-per-item-table3 {
border: 1px solid #EAF1FB;
border-top: none;
padding-right: 30px;
.table3 {
border: 1px solid #EAF1FB;
border-top: none;
box-sizing: border-box;
width: 260px;
/* height: 100px; */
position: absolute;
right: -25;
width: 630px;
page-break-inside: avoid;
page-break-before: auto;
page-break-after: auto;
}
td.estimate-total1 {
@ -370,6 +366,32 @@
border-bottom:1px solid #E8E8E8;
border-top:1px solid #E8E8E8;
}
.notes {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: 300;
font-size: 12px;
color: #595959;
margin-top: 15px;
margin-left: 30px;
width: 442px;
text-align: left;
}
.notes-label {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: normal;
font-size: 15px;
line-height: 22px;
letter-spacing: 0.05em;
color: #040405;
width: 108px;
height: 19.87px;
padding-bottom: 10px;
}
</style>
</head>
<body>
@ -427,6 +449,7 @@
</div>
</div>
@include('app.pdf.estimate.partials.table')
@include('app.pdf.estimate.partials.notes')
</div>
</body>
</html>

View File

@ -0,0 +1,6 @@
<div class="notes">
<div class="notes-label">
Notes
</div>
{{$estimate->notes}}
</div>

View File

@ -1,47 +1,54 @@
<table width="100%" class="table2" cellspacing="0" border="0">
<tr class="main-table-header">
<td width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</td>
<td width="17%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Quantity</td>
<td width="18%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 40px">Price</td>
<td width="10%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 10px">Discount</td>
<td width="15%" class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</td>
@if($estimate->discount_per_item === 'NO')
<th width="80%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
@else
<th width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
@endif
<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>
@if($estimate->discount_per_item === 'YES')
<th width="10%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 10px">Discount</th>
@endif
<th width="15%" class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</th>
</tr>
@foreach ($estimate->items as $item)
<tr class="item-details">
<td width="40%" 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 style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{{ $item->description }}</span>
</td>
<td width="17%" class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px">{{$item->quantity}}</td>
<td width="18%" class="inv-item items" style="text-align: left; color: #040405; padding-left: 40px">{{$item->price/100}}</td>
{{-- <td width="10%" class="inv-item items" style="text-align: left; color: #040405; padding-left: 10px">{{$item->discount/100}}%</td> --}}
<td width="10%" class="inv-item items" style="text-align: left; color: #040405; padding-left: 10px">
@if($item->discount_type === 'fixed')
{{$item->discount_val/100}}
@endif
@if($item->discount_type === 'percentage')
{{$item->discount}}%
@endif
</td>
<td width="15%" 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; padding-right: 20px">{{$item->quantity}}</td>
<td class="inv-item items" style="text-align: left; color: #040405; padding-left: 40px">{{$item->price/100}}</td>
@if($estimate->discount_per_item === 'YES')
<td class="inv-item items" style="text-align: left; color: #040405; padding-left: 10px">
@if($item->discount_type === 'fixed')
{{$item->discount_val/100}}
@endif
@if($item->discount_type === 'percentage')
{{$item->discount}}%
@endif
</td>
@endif
<td class="inv-item items" style="text-align: right; color: #040405">{{$item->total/100}}</td>
</tr>
@endforeach
</table>
<table width="100%" cellspacing="0px" border="0" class="text-per-item-table3 @if(count($estimate->items) > 12) page-break @endif">
<table width="100%" style="margin-left:420px" cellspacing="0px" border="0" class="table3">
<tr>
<td class="no-borde" style="color: #55547A; padding-left:10px; line-height: 18px; 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"
style="padding-right:10px; text-align: right; line-height: 18px; font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($estimate->sub_total) !!}</td>
style="padding-right:10px; text-align: right; font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($estimate->sub_total) !!}</td>
</tr>
@if ($estimate->tax_per_item === 'YES')
@for ($i = 0; $i < count($labels); $i++)
<tr>
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; line-height: 18px; color: #55547A;">
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
{{$labels[$i]}}
</td>
<td class="no-border items padd8" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; line-height: 18px; color: #040405">
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
{!! format_money_pdf($taxes[$i]) !!}
</td>
</tr>
@ -49,10 +56,10 @@
@else
@foreach ($estimate->taxes as $tax)
<tr>
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; line-height: 18px; color: #55547A;">
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
{{$tax->name.' ('.$tax->percent.'%)'}}
</td>
<td class="no-border items padd8" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; line-height: 18px; color: #040405">
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
{!! format_money_pdf($tax->amount) !!}
</td>
</tr>
@ -62,29 +69,33 @@
@if ($estimate->discount_per_item === 'NO')
<tr>
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
Discount
Discount ({{$estimate->discount}}%)
</td>
<td class="no-border items padd8" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
@if($estimate->discount_type === 'fixed')
{!! format_money_pdf($estimate->discount_val) !!}
@endif
@if($estimate->discount_type === 'percentage')
{{$estimate->discount}}% ({!! format_money_pdf($estimate->discount_val) !!})
{!! format_money_pdf($estimate->discount_val) !!}
@endif
</td>
</tr>
@endif
<tr >
<tr>
<td style="padding:3px 0px"></td>
<td style="padding:3px 0px"></td>
</tr>
<tr>
<td class="no-border total-border-left"
style="padding-left:10px; padding-bottom:10px; text-align:left; padding-top:20px; font-size:12px; line-height: 18px; color: #55547A;"
style="padding-left:10px; padding-bottom:10px; text-align:left; padding-top:20px; font-size:12px; color: #55547A;"
>
<label class="total-bottom"> Total </label>
</td>
<td
class="no-border total-border-right items padd8"
style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; line-height: 18px; padding-top:20px; color: #5851DB"
style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; padding-top:20px; color: #5851DB"
>
{!! format_money_pdf($estimate->total)!!}
{!! format_money_pdf($estimate->total)!!}
</td>
</tr>
</table>

View File

@ -72,6 +72,7 @@
.wrapper {
display: block;
padding-top: 60px;
padding-bottom: 60px;
}
.address {
@ -244,6 +245,8 @@
margin-top: 35px;
border-bottom: 1px solid #EAF1FB;
padding: 0px 30px 0 30px;
page-break-before: avoid;
page-break-after: auto;
}
.table2 hr {
@ -257,7 +260,7 @@
padding: 5px;
}
tr.main-table-header td {
tr.main-table-header th {
border-bottom: 1px solid #EAF1FB;
font-style: normal;
font-weight: normal;
@ -284,26 +287,36 @@
padding-bottom: 8px;
}
.table3 {
border: 1px solid #EAF1FB;
border-top: none;
padding-right: 30px;
box-sizing: border-box;
width: 230px;
height: 100px;
position: absolute;
right: -25;
.padd2 {
padding-top: 2px;
padding-bottom: 2px;
}
.text-per-item-table3 {
border: 1px solid #EAF1FB;
.table3 {
/* border: 1px solid #EAF1FB; */
border-top: none;
padding-right: 30px;
/* padding-right: 30px; */
box-sizing: border-box;
width: 260px;
/* height: 100px; */
position: absolute;
right: -25;
width: 630px;
/* position: absolute;
right: -25; */
page-break-inside: avoid;
page-break-before: auto;
page-break-after: auto;
}
.total-border-left {
border: 1px solid #E8E8E8!important;
border-right: 0px !important;
padding-top: 0px;
padding:8px !important;
}
.total-border-right {
border: 1px solid #E8E8E8!important;
border-left: 0px !important;
padding-top: 0px;
padding:8px !important;
}
.inv-item {
@ -323,6 +336,30 @@
color:rgba(0, 0, 0, 0.85);
}
.notes {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: 300;
font-size: 12px;
color: #595959;
margin-top: 15px;
margin-left: 30px;
width: 442px;
text-align: left;
}
.notes-label {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: normal;
font-size: 15px;
line-height: 22px;
letter-spacing: 0.05em;
color: #040405;
width: 108px;
height: 19.87px;
padding-bottom: 10px;
}
</style>
</head>
@ -380,7 +417,10 @@
</div>
<div style="clear: both;"></div>
</div>
@include('app.pdf.invoice.partials.table')
<div style="position:relative">
@include('app.pdf.invoice.partials.table')
</div>
@include('app.pdf.invoice.partials.notes')
</div>
</body>
</html>

View File

@ -74,6 +74,7 @@
.wrapper {
display: block;
padding-top: 110px;
padding-bottom: 60px;
}
.address {
@ -245,6 +246,8 @@
margin-top: 200px;
border-bottom: 1px solid #EAF1FB;
padding: 0px 30px 0 30px;
page-break-before: avoid;
page-break-after: auto;
}
.table2 hr {
@ -258,7 +261,7 @@
padding: 5px;
}
tr.main-table-header td {
tr.main-table-header th {
border-bottom: 1px solid #EAF1FB;
font-style: normal;
font-weight: normal;
@ -295,15 +298,19 @@
padding-bottom: 8px;
}
.padd2 {
padding-top: 2px;
padding-bottom: 2px;
}
.table3 {
border: 1px solid #EAF1FB;
border-top: none;
padding-right: 30px;
box-sizing: border-box;
width: 230px;
height: 100px;
position: absolute;
right: -25;
width: 630px;
page-break-inside: avoid;
page-break-before: auto;
page-break-after: auto;
}
.text-per-item-table3 {
@ -361,6 +368,32 @@
margin-bottom:1px;
margin-top:0;
}
.notes {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: 300;
font-size: 12px;
color: #595959;
margin-top: 15px;
margin-left: 30px;
width: 442px;
text-align: left;
}
.notes-label {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: normal;
font-size: 15px;
line-height: 22px;
letter-spacing: 0.05em;
color: #040405;
width: 108px;
height: 19.87px;
padding-bottom: 10px;
}
</style>
</head>
<body>
@ -403,6 +436,7 @@
</div>
</div>
@include('app.pdf.invoice.partials.table')
@include('app.pdf.invoice.partials.notes')
</div>
</body>
</html>

View File

@ -80,6 +80,7 @@
.wrapper {
display: block;
padding-top: 110px;
padding-bottom: 60px;
}
.address {
@ -233,7 +234,7 @@
.main-table-header {
border-bottom: 1px solid red;
}
tr.main-table-header td {
tr.main-table-header th {
font-style: normal;
font-weight: 600;
font-size: 12px;
@ -249,6 +250,8 @@
margin-top: 188px;
border-bottom: 1px solid #EAF1FB;
padding: 0px 30px 0 30px;
page-break-before: avoid;
page-break-after: auto;
}
.table2 hr {
@ -284,15 +287,19 @@
padding-bottom: 8px;
}
.padd2 {
padding-top: 2px;
padding-bottom: 2px;
}
.table3 {
border: 1px solid #EAF1FB;
border-top: none;
padding-right: 30px;
box-sizing: border-box;
width: 230px;
height: 100px;
position: absolute;
right: -25;
width: 630px;
page-break-inside: avoid;
page-break-before: auto;
page-break-after: auto;
}
.text-per-item-table3 {
@ -370,6 +377,32 @@
border-bottom:1px solid #E8E8E8;
border-top:1px solid #E8E8E8;
}
.notes {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: 300;
font-size: 12px;
color: #595959;
margin-top: 15px;
margin-left: 30px;
width: 442px;
text-align: left;
}
.notes-label {
font-family: 'Roboto', sans-serif;
font-style: normal;
font-weight: normal;
font-size: 15px;
line-height: 22px;
letter-spacing: 0.05em;
color: #040405;
width: 108px;
height: 19.87px;
padding-bottom: 10px;
}
</style>
</head>
<body>
@ -427,6 +460,7 @@
</div>
</div>
@include('app.pdf.invoice.partials.table')
@include('app.pdf.invoice.partials.notes')
</div>
</body>
</html>

View File

@ -0,0 +1,6 @@
<div class="notes">
<div class="notes-label">
Notes
</div>
{{$invoice->notes}}
</div>

View File

@ -1,46 +1,54 @@
<table width="100%" class="table2" cellspacing="0" border="0">
<tr class="main-table-header">
<td width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</td>
<td width="17%" class="ItemTableHeader" style="text-align: right; color: #55547A; padding-right: 20px">Quantity</td>
<td width="18%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 40px">Price</td>
<td width="10%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 10px">Discount</td>
<td width="15%" class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</td>
@if($invoice->discount_per_item === 'NO')
<th width="80%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
@else
<th width="40%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 0px">Items</th>
@endif
<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>
@if($invoice->discount_per_item === 'YES')
<th width="10%" class="ItemTableHeader" style="text-align: left; color: #55547A; padding-left: 10px">Discount</th>
@endif
<th width="15%" class="ItemTableHeader" style="text-align: right; color: #55547A;">Amount</th>
</tr>
@foreach ($invoice->items as $item)
<tr class="item-details">
<td width="40%" 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 style="text-align: left; color: #595959; font-size: 9px; font-weight:300; line-height: 12px;">{{ $item->description }}</span>
</td>
<td width="17%" class="inv-item items" style="text-align: right; color: #040405; padding-right: 20px">{{$item->quantity}}</td>
<td width="18%" class="inv-item items" style="text-align: left; color: #040405; padding-left: 40px">{{$item->price/100}}</td>
<td width="10%" class="inv-item items" style="text-align: left; color: #040405; padding-left: 10px">
@if($item->discount_type === 'fixed')
{{$item->discount_val/100}}
@endif
@if($item->discount_type === 'percentage')
{{$item->discount}}%
@endif
</td>
<td width="15%" 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; padding-right: 20px">{{$item->quantity}}</td>
<td class="inv-item items" style="text-align: left; color: #040405; padding-left: 40px">{{$item->price/100}}</td>
@if($invoice->discount_per_item === 'YES')
<td class="inv-item items" style="text-align: left; color: #040405; padding-left: 10px">
@if($item->discount_type === 'fixed')
{{$item->discount_val/100}}
@endif
@if($item->discount_type === 'percentage')
{{$item->discount}}%
@endif
</td>
@endif
<td class="inv-item items" style="text-align: right; color: #040405">{{$item->total/100}}</td>
</tr>
@endforeach
</table>
<table width="100%" cellspacing="0px" border="0" class="text-per-item-table3 @if(count($invoice->items) > 12) page-break @endif">
<table width="100%" cellspacing="0px" style="margin-left:420px" border="0" class="table3 @if(count($invoice->items) > 12) page-break @endif">
<tr>
<td class="no-borde" style="color: #55547A; padding-left:10px; line-height: 18px; 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"
style="padding-right:10px; text-align: right; line-height: 18px; font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($invoice->sub_total) !!}</td>
style="padding-right:10px; text-align: right; font-size:12px; color: #040405; font-weight: 500;">{!! format_money_pdf($invoice->sub_total) !!}</td>
</tr>
@if ($invoice->tax_per_item === 'YES')
@for ($i = 0; $i < count($labels); $i++)
<tr>
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; line-height: 18px; color: #55547A;">
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
{{$labels[$i]}}
</td>
<td class="no-border items padd8" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; line-height: 18px; color: #040405">
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
{!! format_money_pdf($taxes[$i]) !!}
</td>
</tr>
@ -48,10 +56,10 @@
@else
@foreach ($invoice->taxes as $tax)
<tr>
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; line-height: 18px; color: #55547A;">
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
{{$tax->name.' ('.$tax->percent.'%)'}}
</td>
<td class="no-border items padd8" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; line-height: 18px; color: #040405">
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
{!! format_money_pdf($tax->amount) !!}
</td>
</tr>
@ -61,27 +69,31 @@
@if ($invoice->discount_per_item === 'NO')
<tr>
<td class="no-border" style="padding-left:10px; text-align:left; font-size:12px; color: #55547A;">
Discount
Discount ({{$invoice->discount}}%)
</td>
<td class="no-border items padd8" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
<td class="no-border items padd2" style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; color: #040405">
@if($invoice->discount_type === 'fixed')
{!! format_money_pdf($invoice->discount_val) !!}
@endif
@if($invoice->discount_type === 'percentage')
{{$invoice->discount}}% ({!! format_money_pdf($invoice->discount_val) !!})
{!! format_money_pdf($invoice->discount_val) !!}
@endif
</td>
</tr>
@endif
<tr style="border: 1px solid;" >
<tr>
<td style="padding:3px 0px"></td>
<td style="padding:3px 0px"></td>
</tr>
<tr>
<td class="no-border total-border-left"
style="padding-left:10px; padding-bottom:10px; text-align:left; padding-top:20px; font-size:12px; line-height: 18px; color: #55547A;"
style="padding-left:10px; padding-bottom:10px; text-align:left; padding-top:20px; font-size:12px; color: #55547A;"
>
<label class="total-bottom"> Total </label>
</td>
<td
class="no-border total-border-right items padd8"
style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; line-height: 18px; padding-top:20px; color: #5851DB"
style="padding-right:10px; font-weight: 500; text-align: right; font-size:12px; padding-top:20px; color: #5851DB"
>
{!! format_money_pdf($invoice->total)!!}
</td>