remove unused files and refactor variable names and function names

This commit is contained in:
Mohit Panjwani
2019-11-15 21:02:53 +05:30
parent 9a3e52b658
commit 5d70832f20
43 changed files with 182108 additions and 1664 deletions

View File

@ -3,7 +3,6 @@ namespace Crater;
use Illuminate\Database\Eloquent\Model;
use Crater\State;
use Crater\Country;
class City extends Model
{

View File

@ -2,7 +2,6 @@
namespace Crater;
use Illuminate\Database\Eloquent\Model;
use Crater\User;
class CompanySetting extends Model
{

View File

@ -3,7 +3,6 @@ namespace Crater;
use Illuminate\Database\Eloquent\Model;
use Crater\State;
use Crater\Country;
class Country extends Model
{

View File

@ -218,6 +218,7 @@ class Estimate extends Model
if ($estimate->taxes()->exists()) {
$estimate->taxes()->delete();
}
$estimate->delete();
return true;

View File

@ -2,21 +2,14 @@
namespace Crater\Http\Controllers;
use Illuminate\Http\Request;
use Crater\Expense;
use Crater\Http\Requests;
use Crater\Invoice;
use Crater\Payment;
use Crater\PdfSetting;
use PDF;
use Crater\Currency;
use Crater\CompanySetting;
use Crater\Estimate;
use Crater\Item;
use Crater\User;
use Crater\Company;
use Crater\InvoiceTemplate;
use Crater\EstimateTemplate;
use Auth;
use Crater\Mail\EstimateViewed;
use Crater\Mail\InvoiceViewed;

View File

@ -108,6 +108,7 @@ class Item extends Model
if ($item->estimateItems()->exists() && $item->estimateItems()->count() > 0) {
return false;
}
$item->delete();
return true;

View File

@ -18,7 +18,7 @@ class Updater
$data = null;
$path = null;
$url = '/downloads/file/'.$version.'?type=update';
$url = 'https://craterapp.com/downloads/file/'.$version.'?type=update';
$response = static::getRemote($url, ['timeout' => 100, 'track_redirects' => true]);
@ -99,7 +99,7 @@ class Updater
public static function checkForUpdate()
{
$data = null;
$url = '/downloads/check/latest/'.Setting::getSetting('version');
$url = 'https://craterapp.com/downloads/check/latest/'. Setting::getSetting('version');
$response = static::getRemote($url, ['timeout' => 100, 'track_redirects' => true]);

View File

@ -239,6 +239,7 @@ class User extends Authenticatable implements HasMedia
if ($customer->addresses()->exists()) {
$customer->addresses()->delete();
}
$customer->delete();
return true;

View File

@ -11453,6 +11453,10 @@ code,
align-items: center;
}
.swal-icon--custom {
height: 70px !important;
}
.site-header {
background-color: #5851D8;
height: 60px;
@ -14938,6 +14942,12 @@ fieldset[disabled] .multiselect {
color: #FB7178;
}
@media (max-width: 480px) {
.base-modal .item-modal .input-label {
text-align: left;
}
}
.template-modal .template-container {
display: flex;
justify-content: flex-start;
@ -15009,6 +15019,12 @@ fieldset[disabled] .multiselect {
justify-content: flex-end;
}
@media (max-width: 480px) {
.base-modal .customer-modal .input-label {
text-align: left;
}
}
.tax-type-modal .card-footer {
display: flex;
justify-content: flex-end;
@ -15057,6 +15073,16 @@ fieldset[disabled] .multiselect {
color: #FB7178;
}
@media (max-width: 480px) {
.base-modal .category-modal .input-label {
text-align: left;
}
}
.dashboard .dashboard-table .table-component .dashboard-recent-invoice-options .dropdown-container {
margin: 10px 5px 0 -75px;
}
.dashbox {
background-color: #fff;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
@ -15901,6 +15927,16 @@ fieldset[disabled] .multiselect {
overflow: hidden;
}
.settings-container .version {
background: #EAF1FB;
color: #A5ACC1;
border: 1px solid #EAF1FB;
box-sizing: border-box;
border-radius: 5px;
padding: 10px;
margin-bottom: 15px;
}
@media (max-width: 480px) {
.settings-container .setting-main-container .setting-card {
overflow: scroll;
@ -15989,6 +16025,7 @@ fieldset[disabled] .multiselect {
.invoice-create-page .address-menu .content {
display: flex;
flex: 1;
flex-direction: column;
}
@ -16371,6 +16408,9 @@ fieldset[disabled] .multiselect {
.invoice-create-page .invoice-foot .invoice-total .section .invoice-amount {
font-size: 18px;
color: #55547A;
display: flex;
justify-content: center;
align-items: center;
}
.invoice-create-page .invoice-foot .invoice-total .section .total {
@ -16745,7 +16785,7 @@ fieldset[disabled] .multiselect {
}
.invoice-index-page .filter-date {
flex: 1;
flex: 2;
display: flex;
margin-right: 40px;
align-items: center;
@ -16769,7 +16809,7 @@ fieldset[disabled] .multiselect {
margin-top: 28px;
}
@media (max-width: 992px) {
@media (max-width: 1240px) {
.invoice-index-page .filter-container {
flex-direction: column;
}
@ -16852,6 +16892,7 @@ fieldset[disabled] .multiselect {
.estimate-create-page .address-menu .content {
display: flex;
flex: 1;
flex-direction: column;
}
@ -17234,6 +17275,9 @@ fieldset[disabled] .multiselect {
.estimate-create-page .estimate-foot .estimate-total .section .estimate-amount {
font-size: 18px;
color: #55547A;
display: flex;
justify-content: center;
align-items: center;
}
.estimate-create-page .estimate-foot .estimate-total .section .total {
@ -17274,7 +17318,6 @@ fieldset[disabled] .multiselect {
font-weight: 300;
font-size: 12px;
padding-top: 2px;
padding-left: 10px;
}
.estimate-create-page .item-row .item-description textarea {
@ -17420,7 +17463,7 @@ fieldset[disabled] .multiselect {
}
.estimate-index-page .filter-date {
flex: 1;
flex: 2;
display: flex;
margin-right: 40px;
align-items: center;
@ -17444,7 +17487,7 @@ fieldset[disabled] .multiselect {
margin-top: 28px;
}
@media (max-width: 992px) {
@media (max-width: 1240px) {
.estimate-index-page .filter-container {
flex-direction: column;
}
@ -17963,6 +18006,16 @@ fieldset[disabled] .multiselect {
overflow: hidden;
}
.settings-container .version {
background: #EAF1FB;
color: #A5ACC1;
border: 1px solid #EAF1FB;
box-sizing: border-box;
border-radius: 5px;
padding: 10px;
margin-bottom: 15px;
}
@media (max-width: 480px) {
.settings-container .setting-main-container .setting-card {
overflow: scroll;
@ -18096,6 +18149,9 @@ fieldset[disabled] .multiselect {
border-radius: 50%;
height: 21px;
width: 21px;
display: flex;
align-items: center;
justify-content: center;
}
.wizard .indicator-line .steps.completed .icon-check {
@ -18266,8 +18322,6 @@ fieldset[disabled] .multiselect {
.customer-create .same-address-checkbox-container {
display: flex;
justify-content: flex-end;
padding-left: 12px;
margin-bottom: 1.5rem;
align-items: center;
justify-content: flex-end;
@ -18318,7 +18372,6 @@ fieldset[disabled] .multiselect {
.customer-create .same-address-checkbox-container {
display: flex;
justify-content: flex-start;
padding-left: 15px;
margin-bottom: 0rem;
}
@ -18440,7 +18493,7 @@ fieldset[disabled] .multiselect {
}
}
.inv-status-due {
.inv-status-overdue {
background: #FED7D7;
font-size: 13px;
color: #9B2C2C;
@ -18455,9 +18508,9 @@ fieldset[disabled] .multiselect {
}
.inv-status-unpaid {
background: rgba(246, 208, 154, 0.4);
background: #F8EDCB;
font-size: 13px;
color: #A96E1A;
color: #6C432E;
padding: 5px 10px;
}
@ -18490,9 +18543,9 @@ fieldset[disabled] .multiselect {
}
.inv-status-partially_paid {
background: #E1E0EA;
background: #C9E3EC;
font-size: 13px;
color: #312F57;
color: #1E576C;
padding: 5px 10px;
}

File diff suppressed because one or more lines are too long

181958
public/assets/js/app.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -182,7 +182,7 @@ export default {
list_of_items: 'This section will contain the list of items.',
select_a_unit: 'select unit',
item_attached_message: 'Cannot delete an item already in use',
item_attached_message: 'Cannot delete an item which is already in use',
confirm_delete: 'You will not be able to recover this Item | You will not be able to recover these Items',
created_message: 'Item created successfully',
updated_message: 'Item updated successfully',
@ -227,7 +227,7 @@ export default {
add_estimate: 'Add Estimate',
save_estimate: 'Save Estimate',
confirm_conversion: 'You want to convert this Estimate into Invoice?',
conversion_message: 'Conversion successful',
conversion_message: 'Invoice created successful',
confirm_send_estimate: 'This estimate will be sent via email to the customer',
confirm_mark_as_sent: 'This estimate will be marked as sent',
confirm_mark_as_accepted: 'This estimate will be marked as Accepted',

View File

@ -1,96 +0,0 @@
<template>
<div class="main-content categoriescreate">
<div class="page-header">
<h3 class="page-title">{{ $t('categories.new_category') }}</h3>
<ol class="breadcrumb">
<li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('general.home') }}</router-link></li>
<li class="breadcrumb-item"><router-link slot="item-title" to="/admin/expenses">{{ $tc('categorie.category',2) }}</router-link></li>
<li class="breadcrumb-item"><a href="#">{{ $t('categories.new_category') }}</a></li>
</ol>
<div class="page-actions">
<router-link slot="item-title" to="/admin/expenses">
<base-button class="btn btn-primary" color="theme">
<font-awesome-icon icon="backward" class="mr-2"/> {{ $t('general.go_back') }}
</base-button>
</router-link>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="card">
<form action="" @submit.prevent="submitCategoryData">
<div class="card-body">
<div class="form-group">
<label class="control-label">{{ $t('expenses.categories.title') }}</label><span class="text-danger"> *</span>
<base-input
:invalid="$v.formData.name.$error"
v-model.trim="formData.name"
type="text"
name="name"
@input="$v.formData.name.$touch()"
/>
<div v-if="$v.formData.name.$error">
<span v-if="!$v.formData.name.required" class="text-danger">{{ $t('validation.required') }}</span>
<span v-if="!$v.formData.name.minLength" class="text-danger"> {{ $tc('validation.name_min_length', $v.formData.name.$params.minLength.min, {count: $v.formData.name.$params.minLength.min}) }}</span>
</div>
</div>
<div class="form-group">
<label for="description">{{ $t('expenses.categories.description') }}</label>
<base-text-area v-model="formData.description" rows="5" name="description" />
</div>
<base-button icon="save" type="submit" color="theme">
{{ $t('general.save') }}
</base-button>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import { validationMixin } from 'vuelidate'
import { mapActions } from 'vuex'
const { required, minLength } = require('vuelidate/lib/validators')
export default {
mixins: [validationMixin],
data () {
return {
formData: {
name: null,
description: null
}
}
},
validations: {
formData: {
name: {
required,
minLength: minLength(3)
}
}
},
mounted () {
},
methods: {
...mapActions('category', [
'loadData',
'addCategory'
]),
async submitCategoryData () {
this.$v.formData.$touch()
if (this.$v.$invalid) {
return true
}
let response = await this.addCategory({ ...this.formData })
if (response.data.success) {
window.toastr['success'](response.data.success)
this.$router.push('/admin/expenses')
return true
}
window.toastr['error'](response.data.error)
return true
}
}
}
</script>

View File

@ -1,114 +0,0 @@
<template>
<div class="main-content categoriescreate">
<div class="page-header">
<h3 v-if="!isEdit" class="page-title">{{ $t('categories.add_category') }}</h3>
<h3 v-else class="page-title">{{ $t('navigation.edit') }} {{ $tc('navigation.category',1) }}</h3>
<ol class="breadcrumb">
<li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('navigation.home') }}</router-link></li>
<li class="breadcrumb-item"><router-link slot="item-title" to="/admin/expenses">{{ $tc('navigation.category',2) }}</router-link></li>
<li v-if="!isEdit" class="breadcrumb-item"><a href="#">{{ $t('expenses.categories.add_category') }} {{ $tc('navigation.category', 1) }}</a></li>
<li v-else class="breadcrumb-item"><a href="#">{{ $t('navigation.edit') }} {{ $tc('navigation.category', 1) }}</a></li>
</ol>
<div class="page-actions">
<router-link slot="item-title" to="/admin/expenses">
<base-button icon="backward" color="theme">
{{ $t('navigation.go_back') }}
</base-button>
</router-link>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="card">
<form action="" @submit.prevent="submitCategoryData">
<div class="card-body">
<div class="form-group">
<label class="control-label">{{ $t('expenses.categories.title') }}</label><span class="text-danger"> *</span>
<input
:class="{ error: $v.formData.name.$error }"
v-model.trim="formData.name"
type="text"
name="name"
class="form-control"
@input="$v.formData.name.$touch()"
>
<div v-if="$v.formData.name.$error">
<span v-if="!$v.formData.name.required" class="text-danger">{{ $t('validation.required') }}</span>
<span v-if="!$v.formData.name.minLength" class="text-danger"> {{ $tc('validation.name_min_length', $v.formData.name.$params.minLength.min, {count: $v.formData.name.$params.minLength.min}) }}</span>
</div>
</div>
<div class="form-group">
<label for="description">{{ $t('expenses.categories.description') }}</label>
<textarea v-model="formData.description" class="form-control" rows="5" name="description" />
</div>
<base-button icon="save" color="theme" type="submit">
{{ $t('navigation.save') }}
</base-button>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import { validationMixin } from 'vuelidate'
import { mapActions } from 'vuex'
const { required, minLength } = require('vuelidate/lib/validators')
export default {
mixins: [validationMixin],
data () {
return {
formData: {
name: null,
description: null
}
}
},
computed: {
isEdit () {
if (this.$route.name === 'categoryedit') {
return true
}
return false
}
},
validations: {
formData: {
name: {
required,
minLength: minLength(3)
}
}
},
mounted () {
this.fetchInitialData()
},
methods: {
...mapActions('category', [
'loadData',
'addCategory',
'editCategory'
]),
async fetchInitialData () {
let response = await this.loadData(this.$route.params.id)
this.formData.name = response.data.category.name
this.formData.description = response.data.category.description
},
async submitCategoryData () {
this.$v.formData.$touch()
if (this.$v.$invalid) {
return true
}
let response = await this.editCategory({ id: this.$route.params.id, editData: { ...this.formData } })
if (response.data.success) {
window.toastr['success'](response.data.success)
this.$router.push('/admin/expenses')
return true
}
window.toastr['error'](response.data.error)
return true
}
}
}
</script>

View File

@ -34,7 +34,7 @@
</v-dropdown>
</div>
</div>
<div class="estimate-si debar">
<div class="estimate-sidebar">
<base-loader v-if="isSearching" />
<div v-else class="side-header">
<base-input

View File

@ -1,589 +0,0 @@
<template>
<div class="invoice-create-page main-content">
<form action="" @submit.prevent="submitInvoiceData">
<div class="page-header">
<h3 class="page-title">{{ $t('invoices.new_invoice') }}</h3>
<ol class="breadcrumb">
<li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('general.home') }}</router-link></li>
<li class="breadcrumb-item"><router-link slot="item-title" to="/admin/invoices">{{ $tc('invoices.invoice', 2) }}</router-link></li>
<li class="breadcrumb-item">{{ $t('invoices.new_invoice') }}</li>
</ol>
<div class="page-actions row">
<base-button class="mr-3" outline color="theme">
{{ $t('general.download_pdf') }}
</base-button>
<base-button
:loading="isLoading"
icon="save"
color="theme"
type="submit">
{{ $t('invoices.save_invoice') }}
</base-button>
</div>
</div>
<div class="row invoice-input-group">
<div class="col-md-5">
<div
v-if="selectedCustomer"
class="show-customer"
>
<div class="row p-2">
<div class="col col-6">
<div v-if="selectedCustomer.billing_address != null" class="row address-menu">
<label class="col-sm-4 px-2 title">{{ $t('general.bill_to') }}</label>
<div class="col-sm p-0 px-2 content">
<label>{{ selectedCustomer.billing_address.name }}</label>
<label>{{ selectedCustomer.billing_address.address_street_1 }}</label>
<label>{{ selectedCustomer.billing_address.address_street_2 }}</label>
<label>
{{ selectedCustomer.billing_address.city.name }}, {{ selectedCustomer.billing_address.state.name }} {{ selectedCustomer.billing_address.zip }}
</label>
<label>{{ selectedCustomer.billing_address.country.name }}</label>
<label>{{ selectedCustomer.billing_address.phone }}</label>
</div>
</div>
</div>
<div class="col col-6">
<div v-if="selectedCustomer.shipping_address != null" class="row address-menu">
<label class="col-sm-4 px-2 title">{{ $t('general.ship_to') }}</label>
<div class="col-sm p-0 px-2 content">
<label>{{ selectedCustomer.shipping_address.name }}</label>
<label>{{ selectedCustomer.shipping_address.address_street_1 }}</label>
<label>{{ selectedCustomer.shipping_address.address_street_2 }}</label>
<label v-show="selectedCustomer.shipping_address.city">
{{ selectedCustomer.shipping_address.city.name }}, {{ selectedCustomer.shipping_address.state.name }} {{ selectedCustomer.shipping_address.zip }}
</label>
<label class="country">{{ selectedCustomer.shipping_address.country.name }}</label>
<label class="phone">{{ selectedCustomer.shipping_address.phone }}</label>
</div>
</div>
</div>
</div>
<div class="customer-content">
<label class="email">{{ selectedCustomer.email ? selectedCustomer.email : selectedCustomer.name }}</label>
<label class="action" @click="removeCustomer">{{ $t('general.remove') }}</label>
</div>
</div>
<base-popup v-else class="add-customer">
<div slot="activator" class="add-customer-action">
<font-awesome-icon icon="user" class="customer-icon"/>
<label>{{ $t('customers.new_customer') }}<span class="text-danger"> * </span></label>
</div>
<customer-select />
</base-popup>
</div>
<div class="col invoice-input">
<div class="row mb-3">
<div class="col">
<label>{{ $t('invoices.invoice_date') }}<span class="text-danger"> * </span></label>
<base-date-picker
v-model="newInvoice.invoice_date"
:calendar-button="true"
calendar-button-icon="calendar"
@change="$v.newInvoice.invoice_date.$touch()"
/>
<span v-if="$v.newInvoice.invoice_date.$error && !$v.newInvoice.invoice_date.required" class="text-danger"> {{ $t('validation.required') }} </span>
</div>
<div class="col">
<label>{{ $t('invoices.due_date') }}<span class="text-danger"> * </span></label>
<base-date-picker
v-model="newInvoice.due_date"
:invalid="$v.newInvoice.due_date.$error"
:calendar-button="true"
calendar-button-icon="calendar"
@change="$v.newInvoice.due_date.$touch()"
/>
<span v-if="$v.newInvoice.due_date.$error && !$v.newInvoice.due_date.required" class="text-danger mt-1"> {{ $t('validation.required') }}</span>
</div>
</div>
<div class="row mt-4">
<div class="col">
<label>{{ $t('invoices.invoice_number') }}<span class="text-danger"> * </span></label>
<base-input
:invalid="$v.newInvoice.invoice_number.$error"
:read-only="true"
v-model="newInvoice.invoice_number"
icon="hashtag"
@input="$v.newInvoice.invoice_number.$touch()"
/>
<span v-show="$v.newInvoice.invoice_number.$error && !$v.newInvoice.invoice_number.required" class="text-danger mt-1"> {{ $tc('validation.required') }} </span>
</div>
<div class="col">
<label>{{ $t('invoices.ref_number') }}</label>
<base-input icon="hashtag" type="number"/>
</div>
</div>
</div>
</div>
<table class="item-table">
<colgroup>
<col style="width: 50%;">
<col style="width: 10%;">
<col style="width: 10%;">
<col v-if="discountPerItem === 'YES'" style="width: 15%;">
<col style="width: 15%;">
</colgroup>
<thead class="item-table-header">
<tr>
<th class="text-left">
<span class="column-heading item-heading">
{{ $tc('items.item',2) }}
</span>
</th>
<th class="text-right">
<span class="column-heading">
{{ $t('invoices.item.quantity') }}
</span>
</th>
<th class="text-left">
<span class="column-heading">
{{ $t('invoices.item.price') }}
</span>
</th>
<th v-if="discountPerItem === 'YES'" class="text-right">
<span class="column-heading">
{{ $t('invoices.item.discount') }}
</span>
</th>
<th class="text-right">
<span class="column-heading amount-heading">
{{ $t('invoices.item.amount') }}
</span>
</th>
</tr>
</thead>
<tbody class="item-body">
<invoice-item
v-for="(item, index) in newInvoice.items"
:key="'inv-item-' + item.id"
:index="index"
:item-data="item"
:currency="currency"
:tax-per-item="taxPerItem"
:discount-per-item="discountPerItem"
@remove="removeItem"
@update="updateItem"
@itemValidate="checkItemsData"
/>
</tbody>
</table>
<div class="add-item-action" @click="addItem">
<font-awesome-icon icon="shopping-basket" class="mr-2"/>
{{ $t('invoices.add_item') }}
</div>
<div class="invoice-foot">
<div>
<label>{{ $t('invoices.notes') }}</label>
<base-text-area
v-model="newInvoice.notes"
rows="3"
cols="50"
/>
<label class="mt-3 mb-1 d-block">{{ $t('invoices.invoice_template') }} <span class="text-danger"> * </span></label>
<base-button class="btn-template" icon="pencil-alt" right-icon @click="openTemplateModal" >
<span class="mr-4"> {{ $t('invoices.invoice_template') }} {{ getTemplateId }} </span>
</base-button>
</div>
<div class="invoice-total">
<div class="section">
<label class="invoice-label">{{ $t('invoices.sub_total') }}</label>
<label class="invoice-amount">
<div v-html="$utils.formatMoney(subtotal, currency)" />
</label>
</div>
<div v-for="tax in allTaxes" :key="tax.tax_type_id" class="section">
<label class="invoice-label">{{ tax.name }} - {{ tax.percent }}% </label>
<label class="invoice-amount">
<div v-html="$utils.formatMoney(tax.amount, currency)" />
</label>
</div>
<div v-if="discountPerItem === 'NO' || discountPerItem === null" class="section mt-2">
<label class="invoice-label">{{ $t('invoices.discount') }}</label>
<div
class="btn-group discount-drop-down"
role="group"
>
<base-input
v-model="discount"
input-class="item-discount"
/>
<v-dropdown :show-arrow="false">
<button
slot="activator"
type="button"
class="btn item-dropdown dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
{{ newInvoice.discount_type == 'fixed' ? currency.symbol : '%' }}
</button>
<v-dropdown-item>
<a class="dropdown-item" href="#" @click.prevent="selectFixed">
{{ $t('general.fixed') }}
</a>
</v-dropdown-item>
<v-dropdown-item>
<a class="dropdown-item" href="#" @click.prevent="selectPercentage">
{{ $t('general.percentage') }}
</a>
</v-dropdown-item>
</v-dropdown>
</div>
</div>
<div v-if="taxPerItem === 'NO' || taxPerItem === null">
<tax
v-for="(tax, index) in newInvoice.taxes"
:index="index"
:total="subtotalWithDiscount"
:key="tax.taxKey"
:tax="tax"
:taxes="newInvoice.taxes"
:currency="currency"
:total-tax="totalSimpleTax"
@remove="removeInvoiceTax"
@update="updateTax"
/>
</div>
<base-popup v-if="taxPerItem === 'NO' || taxPerItem === null" ref="taxModal" class="tax-selector">
<div slot="activator" class="float-right">
+ {{ $t('invoices.add_tax') }}
</div>
<tax-select @select="onSelectTax"/>
</base-popup>
<div class="section border-top mt-3">
<label class="invoice-label">{{ $t('invoices.total') }} {{ $t('invoices.amount') }}:</label>
<label class="invoice-amount total">
<div v-html="$utils.formatMoney(total, currency)" />
</label>
</div>
</div>
</div>
</form>
</div>
</template>
<script>
import MultiSelect from 'vue-multiselect'
import InvoiceItem from './Item'
import InvoiceStub from '../../stub/invoice'
import { mapActions, mapGetters } from 'vuex'
import moment from 'moment'
import { validationMixin } from 'vuelidate'
import Guid from 'guid'
import TaxStub from '../../stub/tax'
import Tax from './InvoiceTax'
const { required } = require('vuelidate/lib/validators')
export default {
components: {
InvoiceItem,
MultiSelect,
Tax
},
mixins: [validationMixin],
data () {
return {
newInvoice: {
invoice_date: null,
due_date: null,
invoice_number: null,
user_id: null,
invoice_template_id: 1,
sub_total: null,
total: null,
tax: null,
notes: null,
discount_type: 'fixed',
discount_val: 0,
discount: 0,
items: [{
...InvoiceStub,
id: 1
}],
taxes: []
},
invoiceTemplates: [],
selectedCurrency: '',
newItem: {
...InvoiceStub
},
taxPerItem: null,
discountPerItem: null,
isLoading: false
}
},
validations: {
newInvoice: {
invoice_date: {
required
},
due_date: {
required
},
invoice_number: {
required
}
}
},
computed: {
...mapGetters('currency', [
'defaultCurrency'
]),
currency () {
return this.selectedCurrency
},
subtotalWithDiscount () {
return this.subtotal - this.newInvoice.discount_val
},
total () {
return this.subtotalWithDiscount + this.totalTax
},
subtotal () {
return this.newInvoice.items.reduce(function (a, b) {
return a + b['total']
}, 0)
},
discount: {
get: function () {
return this.newInvoice.discount
},
set: function (newValue) {
if (this.newInvoice.discount_type === 'percentage') {
this.newInvoice.discount_val = (this.subtotal * newValue) / 100
} else {
this.newInvoice.discount_val = newValue * 100
}
this.newInvoice.discount = newValue
}
},
totalSimpleTax () {
return window._.sumBy(this.newInvoice.taxes, function (tax) {
if (!tax.compound_tax) {
return tax.amount
}
return 0
})
},
totalCompoundTax () {
return window._.sumBy(this.newInvoice.taxes, function (tax) {
if (tax.compound_tax) {
return tax.amount
}
return 0
})
},
totalTax () {
if (this.taxPerItem === 'NO' || this.taxPerItem === null) {
return this.totalSimpleTax + this.totalCompoundTax
}
return window._.sumBy(this.newInvoice.items, function (tax) {
return tax.totalTax
})
},
allTaxes () {
let taxes = []
this.newInvoice.items.forEach((item) => {
item.taxes.forEach((tax) => {
let found = taxes.find((_tax) => {
return _tax.tax_type_id === tax.tax_type_id
})
if (found) {
found.amount += tax.amount
} else if (tax.tax_type_id) {
taxes.push({
tax_type_id: tax.tax_type_id,
amount: tax.amount,
percent: tax.percent,
name: tax.name
})
}
})
})
return taxes
},
...mapGetters('customer', [
'selectedCustomer'
]),
...mapGetters('invoice', [
'getTemplateId'
]),
...mapGetters('general', [
'itemDiscount'
])
},
watch: {
selectedCustomer (newVal) {
if (newVal.currency !== null) {
this.selectedCurrency = newVal.currency
} else {
this.selectedCurrency = this.defaultCurrency
}
},
subtotal (newValue) {
if (this.newInvoice.discount_type === 'percentage') {
this.newInvoice.discount_val = (this.newInvoice.discount * newValue) / 100
}
}
},
mounted () {
this.$nextTick(() => {
this.loadData()
})
},
methods: {
...mapActions('modal', [
'openModal'
]),
...mapActions('customer', [
'resetSelectedCustomer'
]),
...mapActions('taxType', {
loadTaxTypes: 'indexLoadData'
}),
...mapActions('invoice', [
'addInvoice',
'fetchInvoice'
]),
selectFixed () {
if (this.newInvoice.discount_type === 'fixed') {
return
}
this.newInvoice.discount_val = this.newInvoice.discount * 100
this.newInvoice.discount_type = 'fixed'
},
selectPercentage () {
if (this.newInvoice.discount_type === 'percentage') {
return
}
this.newInvoice.discount_val = (this.subtotal * this.newInvoice.discount) / 100
this.newInvoice.discount_type = 'percentage'
},
updateTax (data) {
Object.assign(this.newInvoice.taxes[data.index], {...data.item})
},
async loadData () {
let response = await this.fetchInvoice(this.$route.params.id)
this.loadTaxTypes()
if (response.data) {
this.newInvoice = response.data.invoice
this.discountPerItem = response.data.discount_per_item
this.taxPerItem = response.data.tax_per_item
this.selectedCurrency = this.defaultCurrency
this.invoiceTemplates = response.data.invoiceTemplates
}
},
removeCustomer () {
this.resetSelectedCustomer()
},
openTemplateModal () {
this.openModal({
'title': this.$t('general.choose_template'),
'componentName': 'InvoiceTemplate',
'data': this.invoiceTemplates
})
},
addItem () {
this.newInvoice.items.push({...this.newItem, id: (this.newInvoice.items.length + 1)})
},
removeItem (index) {
this.newInvoice.items.splice(index, 1)
},
updateItem (data) {
Object.assign(this.newInvoice.items[data.index], {...data.item})
},
async submitInvoiceData () {
if (!this.checkValid()) {
return false
}
this.isLoading = true
let data = {
...this.newInvoice,
invoice_date: moment(this.newInvoice.invoice_date).format('DD/MM/YYYY'),
due_date: moment(this.newInvoice.due_date).format('DD/MM/YYYY'),
sub_total: this.subtotal,
total: this.total,
tax: this.totalTax,
user_id: null,
invoice_template_id: this.getTemplateId
}
if (this.selectedCustomer != null) {
data.user_id = this.selectedCustomer.id
}
let response = await this.addInvoice(data)
if (response.data) {
window.toastr['success'](this.$t('invoices.created_message'))
this.isLoading = false
this.$route.push('/admin/invoices')
}
},
checkItemsData (index, isValid) {
this.newInvoice.items[index].valid = isValid
},
onSelectTax (selectedTax) {
let amount = 0
if (selectedTax.compound_tax && this.subtotalWithDiscount) {
amount = ((this.subtotalWithDiscount + this.totalSimpleTax) * selectedTax.percent) / 100
} else if (this.subtotalWithDiscount && selectedTax.percent) {
amount = (this.subtotalWithDiscount * selectedTax.percent) / 100
}
this.newInvoice.taxes.push({
...TaxStub,
taxKey: Guid.raw(),
name: selectedTax.name,
percent: selectedTax.percent,
compound_tax: selectedTax.compound_tax,
tax_type_id: selectedTax.id,
amount
})
this.$refs.taxModal.close()
},
removeInvoiceTax (index) {
this.newInvoice.taxes.splice(index, 1)
},
checkValid () {
this.$v.newInvoice.$touch()
window.hub.$emit('checkItems')
let isValid = true
this.newInvoice.items.forEach((item) => {
if (!item.valid) {
isValid = false
}
})
if (this.$v.newInvoice.$invalid === false && isValid === true) {
return true
}
return false
}
}
}
</script>

View File

@ -254,7 +254,7 @@
</a>
</v-dropdown-item>
<v-dropdown-item v-if="row.status == 'DRAFT'">
<a class="dropdown-item" href="#" @click="sentInvoice(row.id)">
<a class="dropdown-item" href="#" @click="markInvoiceAsSent(row.id)">
<font-awesome-icon icon="check-circle" class="dropdown-item-icon" />
{{ $t('invoices.mark_as_sent') }}
</a>
@ -390,8 +390,8 @@ export default {
icon: '/assets/icon/paper-plane-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willSendInvoice) => {
if (willSendInvoice) {
}).then(async (value) => {
if (value) {
const data = {
id: id
}
@ -403,15 +403,15 @@ export default {
}
})
},
async sentInvoice (id) {
async markInvoiceAsSent (id) {
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 (willMarkAsSend) => {
if (willMarkAsSend) {
}).then(async (value) => {
if (value) {
const data = {
id: id
}
@ -499,8 +499,8 @@ export default {
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
if (willDelete) {
}).then(async (value) => {
if (value) {
let res = await this.deleteInvoice(this.id)
if (res.data.success) {
@ -529,8 +529,8 @@ export default {
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
if (willDelete) {
}).then(async (value) => {
if (value) {
let res = await this.deleteMultipleInvoices()
if (res.data.error === 'payment_attached') {
window.toastr['error'](this.$t('invoices.payment_attached_message'), this.$t('general.action_failed'))

View File

@ -1,74 +0,0 @@
<template>
<div class="main-content pdfsetting">
<div class="page-header">
<h3 class="page-title">{{ $t('settings.title') }}</h3>
<ol class="breadcrumb">
<li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('general.home') }}</router-link></li>
<li class="breadcrumb-item"><router-link slot="item-title" to="#">{{ $t('settings.pdf.title') }}</router-link></li>
</ol>
</div>
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-header">
<div class="caption">
<h6>{{ $t('settings.pdf.title') }}</h6>
</div>
<div class="actions">
<base-button color="theme" size="small" @click="submitData">
{{ $t('general.update') }}
</base-button>
</div>
</div>
<div class="card-body">
<div class="row">
<label class="col-md-2 form-control-label">{{ $t('settings.pdf.footer_text') }} : </label>
<div class="col-md-12">
<input v-model="footerText" type="text" class="form-control">
</div>
</div>
<div class="row pdfsetting__img-row">
<label class="col-md-2 form-control-label">{{ $t('settings.pdf.pdf_layout') }} : </label>
<div class="col-md-12">
<image-radio :current-p-d-f="pdfSet" @selectedPDF="selectedPDF"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ImageRadio from '../components/ImageRadio.vue'
import { mapActions, mapMutations } from 'vuex'
export default {
components: {
'image-radio': ImageRadio
},
data () {
return this.$store.state.pdf_setting
// return {
// pdfSet: '1',
// footerText: null
// }
},
mounted () {
this.loadData()
},
methods: {
...mapActions('pdf_setting', [
'loadData',
'submitData'
]),
// async submitData () {
// },
...mapMutations('pdf_setting', [
'selectedPDF'
])
}
}
</script>

View File

@ -106,6 +106,7 @@
<script>
import { mapActions, mapGetters } from 'vuex'
export default {
data () {
return {
@ -135,10 +136,11 @@ export default {
]),
async getTaxSetting (val) {
let response = await axios.get('/api/settings/get-setting?key=tax_per_item')
if (response.data) {
response.data.tax_per_item === 'YES' ?
this.formData.tax_per_item = true :
this.formData.tax_per_item = false
if (response.data && response.data.tax_per_item === 'YES') {
this.formData.tax_per_item = true
} else {
this.formData.tax_per_item = false
}
},
async setTax (val) {
@ -158,15 +160,16 @@ export default {
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true
}).then(async (willDelete) => {
if (willDelete) {
}).then(async (value) => {
if (value) {
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'))
}
window.toastr['error'](this.$t('settings.tax_types.already_in_use'))
}
})
},

View File

@ -8,12 +8,12 @@
</p>
<label class="input-label">Current version</label><br>
<label class="version">1.0.0</label>
<base-button :outline="true" size="large" color="theme" @click="checkUpdate">
<font-awesome-icon :class="{'update': isUpdateAvail}" style="margin-right: 10px;" icon="sync-alt" />
<base-button :outline="true" :disabled="isCheckingforUpdate" size="large" color="theme" @click="checkUpdate" >
<font-awesome-icon :class="{'update': isCheckingforUpdate}" style="margin-right: 10px;" icon="sync-alt" />
{{ $t('settings.update_app.check_update') }}
</base-button>
<hr>
<div v-show="!isUpdating" v-if="isUpdateAvail" class="mt-4 content">
<div v-show="!isUpdating" v-if="isUpdateAvailable" class="mt-4 content">
<h3 class="page-title">{{ $t('settings.update_app.avail_update') }}</h3>
<label class="input-label">{{ $t('settings.update_app.next_version') }}</label><br>
<label class="version">{{ updateData.version }}</label>
@ -41,8 +41,9 @@ export default {
data () {
return {
isShowProgressBar: false,
isUpdateAvail: false,
isUpdateAvailable: false,
isUpdating: false,
isCheckingforUpdate: false,
progress: 10,
interval: null,
description: '',
@ -64,22 +65,24 @@ export default {
this.isUpdating = true
const data = this.updateData
let response = await axios.post('/api/update', data)
console.log(response.data)
this.isUpdating = false
this.isUpdateAvail = false
this.isUpdateAvailable = false
},
async checkUpdate () {
try {
this.isCheckingforUpdate = true
let response = await axios.get('/api/check/update')
console.log(response.data)
this.isCheckingforUpdate = false
if (response.data) {
this.updateData.isMinor = response.data.is_minor
this.updateData.version = response.data.version
this.description = response.data.description
this.isUpdateAvailable = true
}
this.isUpdateAvail = true
} catch (e) {
this.isUpdateAvail = false
this.isUpdateAvailable = false
this.isCheckingforUpdate = false
window.toastr['error']('Something went wrong')
}
}

View File

@ -145,7 +145,7 @@ export default {
name: this.formData.name,
email: this.formData.email
}
if (this.formData.password != null && this.formData.password != undefined && this.formData.password != '') {
if (this.formData.password != null && this.formData.password !== undefined && this.formData.password !== '') {
data = { ...data, password: this.formData.password }
}
let response = await this.editUser(data)

View File

@ -1,126 +0,0 @@
<template>
<div class="main-content">
<div class="page-header">
<h3 class="page-title">{{ $tc('navigation.currency', 2) }}</h3>
<ol class="breadcrumb">
<li class="breadcrumb-item">
<router-link
slot="item-title"
to="/admin/dashboard">
{{ $t('navigation.home') }}
</router-link>
</li>
<li class="breadcrumb-item">
<router-link
slot="item-title"
to="#">
{{ $tc('navigation.currency', 2) }}
</router-link>
</li>
</ol>
</div>
<div class="row">
<div class="col-sm-6">
<div class="card">
<div class="card-header">
<div class="caption">
<h6>{{ $t('settings.currencies.select_currency') }}:</h6>
</div>
</div>
<div class="card-body">
<div class="form-group">
<select
v-model.trim="currencyId"
class="form-control"
@change="selectCurrency()"
>
<option
v-for="(currency, index) in currencies"
:key="index"
:value="currency.id"
>
{{ currency.name }}
</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-header">
<div class="caption">
<h6>{{ $t('settings.currencies.currencies_list') }}</h6>
</div>
<div class="actions">
<router-link slot="item-title" to="currencies/create">
<base-button icon="plus" color="theme" size="small">
{{ $t('navigation.add') }} {{ $t('navigation.new') }}
</base-button>
</router-link>
</div>
</div>
<div class="card-body">
<table-component
ref="table"
:data="currencies"
table-class="table"
sort-by="name"
sort-order="asc"
>
<table-column :label="$t('settings.currencies.name')" show="name" />
<table-column :label="$t('settings.currencies.code')" show="code" />
<table-column :label="$t('settings.currencies.symbol')" show="symbol" />
<table-column :label="$t('settings.currencies.precision')" show="precision" />
<table-column :label="$t('settings.currencies.thousand_separator')" show="thousand_separator" />
<table-column :label="$t('settings.currencies.decimal_separator')" show="decimal_separator" />
<table-column
:sortable="false"
:filterable="false"
:label="$t('settings.currencies.position')"
>
<template slot-scope="row">
<span v-if="row.swap_currency_symbol === 0">{{ $t('settings.currencies.right') }}</span>
<span v-if="row.swap_currency_symbol === 1">{{ $t('settings.currencies.left') }}</span>
</template>
</table-column>
<table-column
:sortable="false"
:filterable="false"
:label="$t('settings.currencies.action')"
>
<template slot-scope="row">
<div class="table__actions">
<router-link slot="item-title" :to="{path: `currencies/${row.id}/edit`}">{{ $t('navigation.edit') }}</router-link>
<div class="table__item--cursor-pointer" @click="removeItems(row.id)">{{ $t('navigation.delete') }}</div>
</div>
</template>
</table-column>
</table-component>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
data () {
return this.$store.state.currency
},
mounted () {
this.indexLoadData()
},
methods: {
...mapActions('currency', [
'indexLoadData',
'removeItems',
'selectCurrency'
])
}
}
</script>

View File

@ -1,185 +0,0 @@
<template>
<div class="main-content currencycreate">
<div class="page-header">
<h3 class="page-title">{{ $t('settings.currencies.add_currency') }}</h3>
<ol class="breadcrumb">
<li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('general.home') }}</router-link></li>
<li class="breadcrumb-item"><router-link slot="item-title" to="/admin/settings/currencies">{{ $tc('settings.currencies.currency',2) }}</router-link></li>
<li class="breadcrumb-item"><a href="#">{{ $t('navigation.add') }}</a></li>
</ol>
<div class="page-actions">
<router-link slot="item-title" to="/admin/settings/currencies">
<base-button icon="backward" color="theme">
{{ $t('navigation.go_back') }}
</base-button>
</router-link>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="card">
<form action="" @submit.prevent="submiteCurrency">
<div class="card-body">
<div class="form-group">
<label class="control-label">{{ $t('settings.currencies.name') }}:</label><span class="required text-danger"> *</span>
<input
:class="{ error: $v.formData.name.$error }"
v-model.trim="formData.name"
type="text"
name="name"
class="form-control"
@input="$v.formData.name.$touch()"
>
<div v-if="$v.formData.name.$error">
<span v-if="!$v.formData.name.required" class="text-danger">{{ $tc('validation.required') }}</span>
</div>
</div>
<div class="form-group">
<label class="control-label">{{ $t('settings.currencies.code') }}:</label><span class="required"> *</span>
<input
:class="{ error: $v.formData.code.$error }"
v-model="formData.code"
type="text"
name="code"
class="form-control"
@input="$v.formData.code.$touch()"
>
<div v-if="$v.formData.code.$error">
<span v-if="!$v.formData.code.required" class="text-danger">{{ $tc('validation.required') }}</span>
</div>
</div>
<div class="form-group">
<label class="control-label">{{ $t('settings.currencies.symbol') }}:</label>
<input
v-model="formData.symbol"
type="text"
name="symbol"
class="form-control"
>
</div>
<div class="form-group">
<label class="control-label">{{ $t('settings.currencies.precision') }}:</label>
<input
v-model="formData.precision"
type="text"
name="precision"
class="form-control"
>
</div>
<div class="form-group">
<label class="control-label">{{ $t('settings.currencies.thousand_separator') }}:</label><span class="required"> *</span>
<input
:class="{ error: $v.formData.thousand_separator.$error }"
v-model="formData.thousand_separator"
type="text"
name="thousand_separator"
class="form-control"
@input="$v.formData.thousand_separator.$touch()"
>
<div v-if="$v.formData.thousand_separator.$error">
<span v-if="!$v.formData.thousand_separator.required" class="text-danger">{{ $tc('validation.required') }}</span>
</div>
</div>
<div class="form-group">
<label class="control-label">{{ $t('settings.currencies.decimal_separator') }}:</label><span class="required"> *</span>
<input
:class="{ error: $v.formData.decimal_separator.$error }"
v-model="formData.decimal_separator"
type="text"
name="decimal_separator"
class="form-control"
@input="$v.formData.decimal_separator.$touch()"
>
<div v-if="$v.formData.decimal_separator.$error">
<span v-if="!$v.formData.decimal_separator.required" class="text-danger">{{ $tc('validation.required') }}</span>
</div>
</div>
<div class="form-group">
<label>{{ $t('settings.currencies.position_of_symbol') }}:</label><span class="required"> *</span>
<select
v-model="formData.swap_currency_symbol"
:class="{ error: $v.formData.swap_currency_symbol.$error }"
class="form-control ls-select2"
name="swap_currency_symbol"
@select="$v.formData.swap_currency_symbol.$touch()"
>
<option value="0">{{ $t('settings.currencies.right') }}</option>
<option value="1">{{ $t('settings.currencies.left') }}</option>
</select>
<div v-if="$v.formData.swap_currency_symbol.$error">
<span v-if="!$v.formData.swap_currency_symbol.required" class="text-danger">{{ $tc('validation.required') }}</span>
</div>
</div>
<base-button color="theme" type="submit">
{{ $t('navigation.add') }}
</base-button>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
import { validationMixin } from 'vuelidate'
const { required } = require('vuelidate/lib/validators')
export default {
mixins: [validationMixin],
data () {
return this.$store.state.currency
},
computed: {
isEdit () {
if (this.$route.name === 'currencyedit') {
return true
}
return false
}
},
validations: {
formData: {
name: {
required
},
code: {
required
},
thousand_separator: {
required
},
decimal_separator: {
required
},
swap_currency_symbol: {
required
}
}
},
mounted () {
if (!this.isEdit) {
return true
}
this.loadData(this.$route.params.id)
},
methods: {
...mapActions('currency', [
'loadData',
'addCurrency',
'editCurrency'
]),
async submiteCurrency () {
this.$v.formData.$touch()
if (this.$v.$invalid) {
return false
}
if (this.isEdit) {
this.editCurrency(this.$route.params.id)
return true
}
this.addCurrency()
return true
}
}
}
</script>

View File

@ -1,10 +1,6 @@
<template>
<div class="card-body">
<form action="" @submit.prevent="next()">
<!-- <div v-if="previewLogo" class="upload-logo">
<label class="form-label">{{ $t('wizard.logo_preview') }}</label><br>
<img v-if="previewLogo" :src="previewLogo" class="preview-logo">
</div> -->
<p class="form-title">{{ $t('wizard.company_info') }}</p>
<p class="form-desc">{{ $t('wizard.company_info_desc') }}</p>
<div class="row mb-4">
@ -155,8 +151,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, maxLength } = require('vuelidate/lib/validators')
const { required, maxLength } = require('vuelidate/lib/validators')
export default {
components: {

View File

@ -34,8 +34,6 @@
</div>
</template>
<script>
import Ls from '../../services/ls'
export default {
data () {
return {

View File

@ -59,7 +59,6 @@
<script>
import MultiSelect from 'vue-multiselect'
import { validationMixin } from 'vuelidate'
import Ls from '../../services/ls'
export default {
components: {

View File

@ -77,7 +77,6 @@
<script>
import MultiSelect from 'vue-multiselect'
import { validationMixin } from 'vuelidate'
import Ls from '../../services/ls'
const { required, requiredIf, sameAs, minLength, email } = require('vuelidate/lib/validators')
export default {

View File

@ -1,380 +0,0 @@
.expenses {
.expenses__date-input {
display: inline-block;
width: 100%;
height: 38px;
padding: 6px 30px 6px 10px;
font-size: 1rem;
line-height: 1.4;
color: #555;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
}
.expenses__date-container--error {
.expenses__date-input {
display: inline-block;
width: 100%;
height: 38px;
padding: 6px 30px 6px 10px;
font-size: 1rem;
line-height: 1.4;
color: #555;
background-color: #fff;
border: 1px solid #F99;
border-radius: 4px;
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
}
}
& .mx-datepicker {
width: 100% !important;
}
& .mx-datepicker-popup {
position: absolute;
width: 250px;
margin-bottom: 1px;
border: 1px solid #d9d9d9;
background-color: #fff;
box-shadow: 0 6px 12px rgba(0,0,0,.175);
z-index: 10;
left: 0 !important;
top: 37.8125px !important;
}
& > .sweet-modal {
-webkit-box-sizing: border-box;
box-sizing: border-box;
background: #fff;
-webkit-box-shadow: 0px 8px 46px rgba(0, 0, 0, 0.08), 0px 2px 6px rgba(0, 0, 0, 0.03);
box-shadow: 0px 8px 46px rgba(0, 0, 0, 0.08), 0px 2px 6px rgba(0, 0, 0, 0.03);
position: absolute;
top: 50%;
left: 50%;
width: 80%;
max-height: 100vh;
overflow-y: auto;
border-radius: 2px;
-webkit-transform: scale(0.9) translate(calc(-50% - 32px), -50%);
transform: scale(0.9) translate(calc(-50% - 32px), -50%);
opacity: 0;
-webkit-transition-property: opacity, -webkit-transform;
transition-property: opacity, -webkit-transform;
transition-property: transform, opacity;
transition-property: transform, opacity, -webkit-transform;
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
-webkit-transition-delay: 0.05s;
transition-delay: 0.05s;
-webkit-transition-timing-function: cubic-bezier(0.52, 0.02, 0.19, 1.02);
transition-timing-function: cubic-bezier(0.52, 0.02, 0.19, 1.02);
}
& > .sweet-modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 9001;
font-size: 14px;
-webkit-font-smoothing: antialiased;
background: rgba(0, 0, 0, 0.6);
opacity: 0;
-webkit-transition: opacity 0.3s;
transition: opacity 0.3s;
-webkit-transform: translate3D(0, 0, 0);
transform: translate3D(0, 0, 0);
-webkit-perspective: 500px;
}
.items-container{
margin: 20px 0;
.head-row .item-field{
background-color : $ls-color-gray--light;
padding: 5px 10px;
}
.head-row .item-actions{
background-color : $white;
}
.foot-row .item-field {
padding: 5px 10px;
text-align: center;
}
.foot-row .item-disc ,.foot-row .item-total{
font-size: 14px;
text-align: right;
line-height: 22px;
}
.item-row{
vertical-align: top;
padding: 10px 0;
border-bottom: 1px solid $ls-color-gray;
}
.head-row{
border-bottom: 0;
}
.item-field{
display: inline-block;
margin-right: -5px;
width: 10.1%;
vertical-align: top;
padding: 5px;
}
.item-total{
text-align: right;
}
.item-title{
width: 20%;
}
.item-desc{
width: 30%;
}
.item-actions{
background-color : $white;
}
}
.static-container {
background-color: $ls-color-gray--light;
display: inline-block;
padding: 20px;
}
.btn-default.dropdown-toggle {
padding: 0.375rem 0.5rem;
}
.static-group {
padding: 5px 0;
.static-title,.static-value{
min-width: 80px;
display: inline-block;
}
.static-title{
min-width: 200px;
text-align: left;
}
}
.static-container{
background-color: $ls-color-gray--light;
display: inline-block;
padding: 20px;
}
.btn-default.dropdown-toggle{
padding: 0.375rem 0.5rem;
}
.static-group{
padding: 5px 0;
.static-title,.static-value{
min-width: 80px;
display: inline-block;
}
.static-title{
min-width: 200px;
text-align: left;
}
}
.drop-zone {
border: 2px dashed $ls-color-gray--light;
height: 110px;
border-radius: 5px;
display: flex;
flex-direction: column;
align-items: center;
.imgbox {
z-index: 100;
width: 100%;
height: 110px;
.dropzone {
min-height: 110px !important;
}
}
.upload {
height: 25px;
width: 25px;
color: $ls-color-gray;
position: absolute;
bottom: 60px;
z-index: 0;
}
.upload-info {
position: absolute;
top: 70px;
left: 35px;
display: flex;
flex-direction: column;
align-items: center;
font-size: 12px;
line-height: 18px;
color: $ls-color-gray;
font-weight: normal;
}
.dz-image-preview {
position: absolute;
top: 28px;
left: 16px;
margin: 0;
min-height: 0;
}
.dz-preview {
width: 110px !important;
height: 110px !important;
display: inline-block !important
}
.dz-preview .dz-image {
width: 110px !important;
height: 110px !important;
border-radius: 5px !important;
}
.dz-preview .dz-image > div {
width: inherit !important;
height: inherit !important;
background-size: contain !important;
}
.dz-preview .dz-image > img {
width: 100% !important;
}
.dz-preview .dz-details {
display: none;
}
.dz-remove {
height: 25px;
width: 100px;
position: absolute;
top: 70% !important;
right: 5px !important;
}
.dz-message {
font-size: 12px;
font-style: normal;
font-weight: normal;
line-height: 18px;
color: $ls-color-gray;
margin: 0 !important;
position: relative;
top: 40%;
span {
display: flex;
flex-direction: column;
i {
font-style: normal;
font-weight: 900;
font-size: 20px;
line-height: 23px;
margin-bottom: 10px;
}
}
}
}
.dz-message {
font-size: 12px;
font-style: normal;
font-weight: normal;
line-height: 18px;
color: $ls-color-gray;
}
.imgbox #dropzone {
height: 110px !important;
background-color: transparent;
border: none;
}
.imgbox .vue-dropzone {
border: none !important;
}
.header-button-container {
display: flex;
}
.collapse-button-container {
display: none !important;
}
.collapse-button {
display: none;
}
}
@media(max-width: $x-small-breakpoint ) {
.expenses {
.page-actions {
position: relative;
-webkit-transform: none;
-ms-transform: none;
-o-transform: none;
transform: none;
display: flex;
flex-wrap: wrap;
button {
margin-bottom: 10px;
}
}
.page-header {
margin-bottom: 5px;
}
.table-actions {
margin-top: 0px !important;
}
.collapse-button {
width: 100%;
display: flex;
flex-direction: row;
justify-content: center;
}
.header-button-container {
display: none;
}
.collapse-button-container {
margin-top: 8px;
display: block;
}
}
}

View File

@ -34,4 +34,5 @@
color: $ls-color-gray;
margin-bottom: 10px;
}
}

View File

@ -62,7 +62,3 @@
}
}

View File

@ -73,4 +73,5 @@
font-weight: 500;
color: $ls-color-black--light !important;
}
}

View File

@ -24,8 +24,6 @@
}
}
}
.vdp-datepicker__calendar-button {
@ -39,7 +37,8 @@
line-height: 16px;
top: 50%;
left: 20px;
transform: translate(-50%,-50%);
transform: translate(-50%, -50%);
.icon-fa {
color: $ls-color-gray;
}

View File

@ -19,6 +19,7 @@
box-shadow: $shadow-lg;
border-radius: 5px;
}
.selector-menu-above {
top: unset !important;
bottom: 100% !important;

View File

@ -1,5 +1,6 @@
.base-text-area {
width: 100%;
&.text-area-field {
width: 100%;
padding: 8px 13px;
@ -38,5 +39,7 @@
&-icon {
padding-left: 35px;
}
}
}

View File

@ -57,6 +57,7 @@
.btn-icon {
padding: 0.6rem;
line-height: 1em;
i {
text-align: center;
}
@ -160,6 +161,3 @@
opacity: 0.9;
color: $ls-color-primary;
}
.btn-crater-hollow:focus {
}

View File

@ -1,5 +1,4 @@
// cards.scss - Custom Cards
.card {
margin-bottom: 1.5rem;
border: none;

View File

@ -10,7 +10,7 @@
background-color: transparent;
border: 0;
margin: 0;
overflow: visible;
overflow: visible;
}
.hamburger-box {
@ -25,34 +25,44 @@
top: 50%;
left: 4.5px;
right: 4.5px;
margin-top: -2px;
margin-top: -2px;
}
.hamburger-inner, .hamburger-inner::before, .hamburger-inner::after {
.hamburger-inner,
.hamburger-inner::before,
.hamburger-inner::after {
height: 2px;
background-color: $header-buttons-font-color;
border-radius: 2px;
position: absolute;
transition-property: transform;
transition-duration: 0.15s;
transition-timing-function: ease;
transition-timing-function: ease;
}
.hamburger-inner::before, .hamburger-inner::after {
.hamburger-inner::before,
.hamburger-inner::after {
content: "";
display: block;
width:100%;
}
.hamburger-inner::before {
top: -5px;
top: -5px;
}
.hamburger-inner::after {
bottom: -5px;
bottom: -5px;
}
.hamburger--arrowturn.is-active .hamburger-inner {
transform: rotate(-180deg);
}
.hamburger--arrowturn.is-active .hamburger-inner::before {
transform: translate3d(3px, 1px, 0) rotate(45deg) scale(0.7, 1);
transform: translate3d(3px, 1px, 0) rotate(45deg) scale(0.7, 1);
}
.hamburger--arrowturn.is-active .hamburger-inner::after {
transform: translate3d(3px, -1px, 0) rotate(-45deg) scale(0.7, 1);
transform: translate3d(3px, -1px, 0) rotate(-45deg) scale(0.7, 1);
}

View File

@ -23,16 +23,10 @@
@media(max-width: $x-small-breakpoint ) {
.base-modal {
.base-modal .item-modal .input-label{
.item-modal {
.input-label {
text-align: left;
}
}
text-align: left;
}
}
}

View File

@ -58,19 +58,23 @@
0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
}
@-moz-keyframes pace-spinner {
0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
}
@-o-keyframes pace-spinner {
0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
}
@-ms-keyframes pace-spinner {
0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
}
@keyframes pace-spinner {
0% { transform: rotate(0deg); transform: rotate(0deg); }
100% { transform: rotate(360deg); transform: rotate(360deg); }
}
}

View File

@ -290,7 +290,7 @@ table.full-width {
}
.table-component td > span:first-child {
background: $gray--light;
background: $ls-color-gray--light;
color: $ls-color-secondary;
display: none;
font-size: 10px;
@ -346,7 +346,7 @@ table.full-width {
position: relative;
width: 50%;
left: 0;
border: 1px solid $gray--light !important;
border: 1px solid $ls-color-gray--light !important;
&:not(:first-child) {
text-align: center !important;

View File

@ -33,7 +33,7 @@
}
&:hover {
background-color: $gray--very-light;
background-color: $ls-color-gray--very-light;
}
.left {

View File

@ -134,7 +134,7 @@
display: flex;
justify-content: space-between;
margin-bottom: 0;
border: 1px solid $gray--light;
border: 1px solid $ls-color-gray--light;
.left-item,
.right-item {