mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-09-20 00:11:35 +02:00
Added support for taxes to expenses
This commit is contained in:
parent
3498d28d3f
commit
386c606558
@ -12,6 +12,7 @@ use App\Models\Vendor;
|
|||||||
use App\Models\Expense;
|
use App\Models\Expense;
|
||||||
use App\Models\ExpenseCategory;
|
use App\Models\ExpenseCategory;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
|
use App\Models\TaxRate;
|
||||||
use App\Services\ExpenseService;
|
use App\Services\ExpenseService;
|
||||||
use App\Ninja\Repositories\ExpenseRepository;
|
use App\Ninja\Repositories\ExpenseRepository;
|
||||||
use App\Http\Requests\ExpenseRequest;
|
use App\Http\Requests\ExpenseRequest;
|
||||||
@ -237,6 +238,7 @@ class ExpenseController extends BaseController
|
|||||||
'customLabel1' => Auth::user()->account->custom_vendor_label1,
|
'customLabel1' => Auth::user()->account->custom_vendor_label1,
|
||||||
'customLabel2' => Auth::user()->account->custom_vendor_label2,
|
'customLabel2' => Auth::user()->account->custom_vendor_label2,
|
||||||
'categories' => ExpenseCategory::whereAccountId(Auth::user()->account_id)->orderBy('name')->get(),
|
'categories' => ExpenseCategory::whereAccountId(Auth::user()->account_id)->orderBy('name')->get(),
|
||||||
|
'taxRates' => TaxRate::scope()->orderBy('name')->get(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,10 @@ class Expense extends EntityModel
|
|||||||
'bank_id',
|
'bank_id',
|
||||||
'transaction_id',
|
'transaction_id',
|
||||||
'expense_category_id',
|
'expense_category_id',
|
||||||
|
'tax_rate1',
|
||||||
|
'tax_name1',
|
||||||
|
'tax_rate2',
|
||||||
|
'tax_name2',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,4 +36,13 @@ class TaxRate extends EntityModel
|
|||||||
{
|
{
|
||||||
return $this->belongsTo('App\Models\User')->withTrashed();
|
return $this->belongsTo('App\Models\User')->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool|string
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return sprintf('%s: %s%%', $this->name, $this->rate);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2022,6 +2022,8 @@ $LANG = array(
|
|||||||
'archived_expense_categories' => 'Successfully archived :count expense category',
|
'archived_expense_categories' => 'Successfully archived :count expense category',
|
||||||
'restore_expense_category' => 'Restore expense category',
|
'restore_expense_category' => 'Restore expense category',
|
||||||
'restored_expense_category' => 'Successfully restored expense category',
|
'restored_expense_category' => 'Successfully restored expense category',
|
||||||
|
'apply_taxes' => 'Apply taxes',
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -81,9 +81,10 @@
|
|||||||
->data_bind('checked: convert_currency')
|
->data_bind('checked: convert_currency')
|
||||||
->label(' ') !!}
|
->label(' ') !!}
|
||||||
@endif
|
@endif
|
||||||
<br/>
|
|
||||||
|
|
||||||
<div style="display:none" data-bind="visible: enableExchangeRate">
|
<div style="display:none" data-bind="visible: enableExchangeRate">
|
||||||
|
<br/>
|
||||||
<span style="display:none" data-bind="visible: !client_id()">
|
<span style="display:none" data-bind="visible: !client_id()">
|
||||||
{!! Former::select('invoice_currency_id')->addOption('','')
|
{!! Former::select('invoice_currency_id')->addOption('','')
|
||||||
->label(trans('texts.invoice_currency'))
|
->label(trans('texts.invoice_currency'))
|
||||||
@ -106,6 +107,41 @@
|
|||||||
->data_bind("value: convertedAmount, enable: enableExchangeRate")
|
->data_bind("value: convertedAmount, enable: enableExchangeRate")
|
||||||
->append('<span data-bind="html: invoiceCurrencyCode"></span>') !!}
|
->append('<span data-bind="html: invoiceCurrencyCode"></span>') !!}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@if (!$expense || ($expense && (!$expense->tax_name1 && !$expense->tax_name2)))
|
||||||
|
{!! Former::checkbox('apply_taxes')
|
||||||
|
->text(trans('texts.apply_taxes'))
|
||||||
|
->data_bind('checked: apply_taxes')
|
||||||
|
->label(' ') !!}
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div style="display:none" data-bind="visible: apply_taxes">
|
||||||
|
<br/>
|
||||||
|
{!! Former::select('tax_select1')
|
||||||
|
->addOption('','')
|
||||||
|
->label(trans('texts.tax_rate'))
|
||||||
|
->onchange('taxSelectChange(event)')
|
||||||
|
->fromQuery($taxRates) !!}
|
||||||
|
|
||||||
|
<div style="display:none">
|
||||||
|
{!! Former::input('tax_rate1') !!}
|
||||||
|
{!! Former::input('tax_name1') !!}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display:{{ $account->enable_second_tax_rate ? 'block' : 'none' }}">
|
||||||
|
{!! Former::select('tax_select2')
|
||||||
|
->addOption('','')
|
||||||
|
->label(trans('texts.tax_rate'))
|
||||||
|
->onchange('taxSelectChange(event)')
|
||||||
|
->fromQuery($taxRates) !!}
|
||||||
|
|
||||||
|
<div style="display:none">
|
||||||
|
{!! Former::input('tax_rate2') !!}
|
||||||
|
{!! Former::input('tax_name2') !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
||||||
@ -158,6 +194,7 @@
|
|||||||
var vendors = {!! $vendors !!};
|
var vendors = {!! $vendors !!};
|
||||||
var clients = {!! $clients !!};
|
var clients = {!! $clients !!};
|
||||||
var categories = {!! $categories !!};
|
var categories = {!! $categories !!};
|
||||||
|
var taxRates = {!! $taxRates !!};
|
||||||
|
|
||||||
var clientMap = {};
|
var clientMap = {};
|
||||||
for (var i=0; i<clients.length; i++) {
|
for (var i=0; i<clients.length; i++) {
|
||||||
@ -224,6 +261,9 @@
|
|||||||
onClientChange();
|
onClientChange();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setTaxSelect(1);
|
||||||
|
setTaxSelect(2);
|
||||||
|
|
||||||
@if ($data)
|
@if ($data)
|
||||||
// this means we failed so we'll reload the previous state
|
// this means we failed so we'll reload the previous state
|
||||||
window.model = new ViewModel({!! $data !!});
|
window.model = new ViewModel({!! $data !!});
|
||||||
@ -308,6 +348,7 @@
|
|||||||
self.exchange_rate = ko.observable(1);
|
self.exchange_rate = ko.observable(1);
|
||||||
self.should_be_invoiced = ko.observable();
|
self.should_be_invoiced = ko.observable();
|
||||||
self.convert_currency = ko.observable(false);
|
self.convert_currency = ko.observable(false);
|
||||||
|
self.apply_taxes = ko.observable({{ ($expense && ($expense->tax_name1 || $expense->tax_name2)) ? 'true' : 'false' }});
|
||||||
|
|
||||||
self.mapping = {
|
self.mapping = {
|
||||||
'documents': {
|
'documents': {
|
||||||
@ -436,6 +477,39 @@
|
|||||||
window.countUploadingDocuments--;
|
window.countUploadingDocuments--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function taxSelectChange(event) {
|
||||||
|
var $select = $(event.target);
|
||||||
|
var tax = $select.find('option:selected').text();
|
||||||
|
|
||||||
|
var index = tax.lastIndexOf(': ');
|
||||||
|
var taxName = tax.substring(0, index);
|
||||||
|
var taxRate = tax.substring(index + 2, tax.length - 1);
|
||||||
|
|
||||||
|
var selectName = $select.attr('name');
|
||||||
|
var instance = selectName.substring(selectName.length - 1);
|
||||||
|
|
||||||
|
$('#tax_name' + instance).val(taxName);
|
||||||
|
$('#tax_rate' + instance).val(taxRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTaxSelect(instance) {
|
||||||
|
var $select = $('#tax_select' + instance);
|
||||||
|
var taxName = $('#tax_name' + instance).val();
|
||||||
|
var taxRate = $('#tax_rate' + instance).val();
|
||||||
|
if (!taxRate || !taxName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var tax = _.findWhere(taxRates, {name:taxName, rate:taxRate});
|
||||||
|
if (tax) {
|
||||||
|
$select.val(tax.public_id);
|
||||||
|
} else {
|
||||||
|
var option = new Option(taxName + ': ' + taxRate + '%', '');
|
||||||
|
option.selected = true;
|
||||||
|
$select.append(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@stop
|
@stop
|
||||||
|
@ -867,6 +867,10 @@
|
|||||||
item.qty(1);
|
item.qty(1);
|
||||||
item.expense_public_id(expense.public_id());
|
item.expense_public_id(expense.public_id());
|
||||||
item.cost(expense.converted_amount());
|
item.cost(expense.converted_amount());
|
||||||
|
item.tax_rate1(expense.tax_rate1());
|
||||||
|
item.tax_name1(expense.tax_name1());
|
||||||
|
item.tax_rate2(expense.tax_rate2());
|
||||||
|
item.tax_name2(expense.tax_name2());
|
||||||
}
|
}
|
||||||
model.invoice().invoice_items.push(blank);
|
model.invoice().invoice_items.push(blank);
|
||||||
model.invoice().has_expenses(true);
|
model.invoice().has_expenses(true);
|
||||||
|
Loading…
Reference in New Issue
Block a user