mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Add inclusive tax rates #552
This commit is contained in:
parent
4307bb2984
commit
c4cdc45a93
@ -253,7 +253,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)->withArchived()->orderBy('name')->get(),
|
'categories' => ExpenseCategory::whereAccountId(Auth::user()->account_id)->withArchived()->orderBy('name')->get(),
|
||||||
'taxRates' => TaxRate::scope()->orderBy('name')->get(),
|
'taxRates' => TaxRate::scope()->whereIsInclusive(false)->orderBy('name')->get(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +328,11 @@ class InvoiceController extends BaseController
|
|||||||
$defaultTax = false;
|
$defaultTax = false;
|
||||||
|
|
||||||
foreach ($rates as $rate) {
|
foreach ($rates as $rate) {
|
||||||
$options[$rate->rate . ' ' . $rate->name] = $rate->name . ' ' . ($rate->rate+0) . '%';
|
$name = $rate->name . ' ' . ($rate->rate+0) . '%';
|
||||||
|
if ($rate->is_inclusive) {
|
||||||
|
$name .= ' - ' . trans('texts.inclusive');
|
||||||
|
}
|
||||||
|
$options[($rate->is_inclusive ? '1 ' : '0 ') . $rate->rate . ' ' . $rate->name] = $name;
|
||||||
|
|
||||||
// load default invoice tax
|
// load default invoice tax
|
||||||
if ($rate->id == $account->default_tax_rate_id) {
|
if ($rate->id == $account->default_tax_rate_id) {
|
||||||
@ -342,7 +346,7 @@ class InvoiceController extends BaseController
|
|||||||
if (isset($options[$key])) {
|
if (isset($options[$key])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$options[$key] = $rate['name'] . ' ' . $rate['rate'] . '%';
|
$options['0 ' . $key] = $rate['name'] . ' ' . $rate['rate'] . '%';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ class ProductController extends BaseController
|
|||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'account' => $account,
|
'account' => $account,
|
||||||
'taxRates' => $account->invoice_item_taxes ? TaxRate::scope()->get(['id', 'name', 'rate']) : null,
|
'taxRates' => $account->invoice_item_taxes ? TaxRate::scope()->whereIsInclusive(false)->get(['id', 'name', 'rate']) : null,
|
||||||
'product' => $product,
|
'product' => $product,
|
||||||
'entity' => $product,
|
'entity' => $product,
|
||||||
'method' => 'PUT',
|
'method' => 'PUT',
|
||||||
@ -94,7 +94,7 @@ class ProductController extends BaseController
|
|||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'account' => $account,
|
'account' => $account,
|
||||||
'taxRates' => $account->invoice_item_taxes ? TaxRate::scope()->get(['id', 'name', 'rate']) : null,
|
'taxRates' => $account->invoice_item_taxes ? TaxRate::scope()->whereIsInclusive(false)->get(['id', 'name', 'rate']) : null,
|
||||||
'product' => null,
|
'product' => null,
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'url' => 'products',
|
'url' => 'products',
|
||||||
|
@ -18,7 +18,8 @@ class TaxRate extends EntityModel
|
|||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name',
|
'name',
|
||||||
'rate'
|
'rate',
|
||||||
|
'is_inclusive',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +20,12 @@ class TaxRateDatatable extends EntityDatatable
|
|||||||
function ($model) {
|
function ($model) {
|
||||||
return $model->rate . '%';
|
return $model->rate . '%';
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type',
|
||||||
|
function ($model) {
|
||||||
|
return $model->is_inclusive ? trans('texts.inclusive') : trans('texts.exclusive');
|
||||||
|
}
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,13 @@ class TaxRateRepository extends BaseRepository
|
|||||||
return DB::table('tax_rates')
|
return DB::table('tax_rates')
|
||||||
->where('tax_rates.account_id', '=', $accountId)
|
->where('tax_rates.account_id', '=', $accountId)
|
||||||
->where('tax_rates.deleted_at', '=', null)
|
->where('tax_rates.deleted_at', '=', null)
|
||||||
->select('tax_rates.public_id', 'tax_rates.name', 'tax_rates.rate', 'tax_rates.deleted_at');
|
->select(
|
||||||
|
'tax_rates.public_id',
|
||||||
|
'tax_rates.name',
|
||||||
|
'tax_rates.rate',
|
||||||
|
'tax_rates.deleted_at',
|
||||||
|
'tax_rates.is_inclusive'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save($data, $taxRate = null)
|
public function save($data, $taxRate = null)
|
||||||
@ -29,7 +35,7 @@ class TaxRateRepository extends BaseRepository
|
|||||||
} else {
|
} else {
|
||||||
$taxRate = TaxRate::createNew();
|
$taxRate = TaxRate::createNew();
|
||||||
}
|
}
|
||||||
|
|
||||||
$taxRate->fill($data);
|
$taxRate->fill($data);
|
||||||
$taxRate->save();
|
$taxRate->save();
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ class TaxRateTransformer extends EntityTransformer
|
|||||||
* @SWG\Property(property="name", type="string", example="GST")
|
* @SWG\Property(property="name", type="string", example="GST")
|
||||||
* @SWG\Property(property="account_key", type="string", example="asimplestring", readOnly=true)
|
* @SWG\Property(property="account_key", type="string", example="asimplestring", readOnly=true)
|
||||||
* @SWG\Property(property="rate", type="float", example=17.5)
|
* @SWG\Property(property="rate", type="float", example=17.5)
|
||||||
|
* @SWG\Property(property="is_inclusive", type="boolean", example=false)
|
||||||
* @SWG\Property(property="updated_at", type="date-time", example="2016-01-01 12:10:00")
|
* @SWG\Property(property="updated_at", type="date-time", example="2016-01-01 12:10:00")
|
||||||
* @SWG\Property(property="archived_at", type="date-time", example="2016-01-01 12:10:00")
|
* @SWG\Property(property="archived_at", type="date-time", example="2016-01-01 12:10:00")
|
||||||
*/
|
*/
|
||||||
@ -23,8 +24,9 @@ class TaxRateTransformer extends EntityTransformer
|
|||||||
'id' => (int) $taxRate->public_id,
|
'id' => (int) $taxRate->public_id,
|
||||||
'name' => $taxRate->name,
|
'name' => $taxRate->name,
|
||||||
'rate' => (float) $taxRate->rate,
|
'rate' => (float) $taxRate->rate,
|
||||||
|
'is_inclusive' => (bool) $taxRate->is_inclusive,
|
||||||
'updated_at' => $this->getTimestamp($taxRate->updated_at),
|
'updated_at' => $this->getTimestamp($taxRate->updated_at),
|
||||||
'archived_at' => $this->getTimestamp($taxRate->deleted_at),
|
'archived_at' => $this->getTimestamp($taxRate->deleted_at),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddInclusiveTaxes extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('tax_rates', function($table)
|
||||||
|
{
|
||||||
|
$table->boolean('is_inclusive')->default(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('companies', function ($table)
|
||||||
|
{
|
||||||
|
$table->enum('bluevine_status', ['ignored', 'signed_up'])->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::statement('UPDATE companies
|
||||||
|
LEFT JOIN accounts ON accounts.company_id = companies.id AND accounts.bluevine_status IS NOT NULL
|
||||||
|
SET companies.bluevine_status = accounts.bluevine_status');
|
||||||
|
|
||||||
|
Schema::table('accounts', function($table)
|
||||||
|
{
|
||||||
|
$table->dropColumn('bluevine_status');
|
||||||
|
$table->text('bcc_email')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('tax_rates', function($table)
|
||||||
|
{
|
||||||
|
$table->dropColumn('is_inclusive');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('companies', function($table)
|
||||||
|
{
|
||||||
|
$table->dropColumn('bluevine_status');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('accounts', function ($table)
|
||||||
|
{
|
||||||
|
$table->enum('bluevine_status', ['ignored', 'signed_up'])->nullable();
|
||||||
|
$table->dropColumn('bcc_email');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -2291,7 +2291,9 @@ $LANG = array(
|
|||||||
'iphone_app_message' => 'Consider downloading our :link',
|
'iphone_app_message' => 'Consider downloading our :link',
|
||||||
'iphone_app' => 'iPhone app',
|
'iphone_app' => 'iPhone app',
|
||||||
'logged_in' => 'Logged In',
|
'logged_in' => 'Logged In',
|
||||||
'switch_to_primary' => 'Switch to your primary company (:name) to manage your plan.'
|
'switch_to_primary' => 'Switch to your primary company (:name) to manage your plan.',
|
||||||
|
'inclusive' => 'Inclusive',
|
||||||
|
'exclusive' => 'Exclusive',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
trans('texts.currency_symbol') . ': <span id="currency_symbol_example"/>' => array('name' => 'show_currency_code', 'value' => 0),
|
trans('texts.currency_symbol') . ': <span id="currency_symbol_example"/>' => array('name' => 'show_currency_code', 'value' => 0),
|
||||||
trans('texts.currency_code') . ': <span id="currency_code_example"/>' => array('name' => 'show_currency_code', 'value' => 1),
|
trans('texts.currency_code') . ': <span id="currency_code_example"/>' => array('name' => 'show_currency_code', 'value' => 1),
|
||||||
])->inline()
|
])->inline()
|
||||||
->check('timer')
|
|
||||||
->label(' ')
|
->label(' ')
|
||||||
->addGroupClass('currrency_radio') !!}
|
->addGroupClass('currrency_radio') !!}
|
||||||
<br/>
|
<br/>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@extends('header')
|
@extends('header')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@parent
|
@parent
|
||||||
|
|
||||||
@include('accounts.nav', ['selected' => ACCOUNT_TAX_RATES])
|
@include('accounts.nav', ['selected' => ACCOUNT_TAX_RATES])
|
||||||
@ -21,15 +21,24 @@
|
|||||||
|
|
||||||
@if ($taxRate)
|
@if ($taxRate)
|
||||||
{{ Former::populate($taxRate) }}
|
{{ Former::populate($taxRate) }}
|
||||||
|
{{ Former::populateField('is_inclusive', intval($taxRate->is_inclusive)) }}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{!! Former::text('name')->label('texts.name') !!}
|
{!! Former::text('name')->label('texts.name') !!}
|
||||||
{!! Former::text('rate')->label('texts.rate')->append('%') !!}
|
{!! Former::text('rate')->label('texts.rate')->append('%') !!}
|
||||||
|
|
||||||
|
{!! Former::radios('is_inclusive')->radios([
|
||||||
|
trans('texts.exclusive') => array('name' => 'is_inclusive', 'value' => 0),
|
||||||
|
trans('texts.inclusive') => array('name' => 'is_inclusive', 'value' => 1),
|
||||||
|
])->inline()
|
||||||
|
->check(0)
|
||||||
|
->label('type') !!}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!! Former::actions(
|
{!! Former::actions(
|
||||||
Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/settings/tax_rates'))->appendIcon(Icon::create('remove-circle')),
|
Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/settings/tax_rates'))->appendIcon(Icon::create('remove-circle')),
|
||||||
Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk'))
|
Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk'))
|
||||||
) !!}
|
) !!}
|
||||||
@ -44,4 +53,4 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@stop
|
@stop
|
||||||
|
@ -65,12 +65,13 @@
|
|||||||
->addColumn(
|
->addColumn(
|
||||||
trans('texts.name'),
|
trans('texts.name'),
|
||||||
trans('texts.rate'),
|
trans('texts.rate'),
|
||||||
|
trans('texts.type'),
|
||||||
trans('texts.action'))
|
trans('texts.action'))
|
||||||
->setUrl(url('api/tax_rates/'))
|
->setUrl(url('api/tax_rates/'))
|
||||||
->setOptions('sPaginationType', 'bootstrap')
|
->setOptions('sPaginationType', 'bootstrap')
|
||||||
->setOptions('bFilter', false)
|
->setOptions('bFilter', false)
|
||||||
->setOptions('bAutoWidth', false)
|
->setOptions('bAutoWidth', false)
|
||||||
->setOptions('aoColumns', [[ "sWidth"=> "40%" ], [ "sWidth"=> "40%" ], ["sWidth"=> "20%"]])
|
->setOptions('aoColumns', [[ "sWidth"=> "25%" ], [ "sWidth"=> "25%" ], ["sWidth"=> "25%"], ["sWidth"=> "25%"]])
|
||||||
->setOptions('aoColumnDefs', [['bSortable'=>false, 'aTargets'=>[2]]])
|
->setOptions('aoColumnDefs', [['bSortable'=>false, 'aTargets'=>[2]]])
|
||||||
->render('datatable') !!}
|
->render('datatable') !!}
|
||||||
|
|
||||||
|
@ -297,19 +297,19 @@
|
|||||||
style="text-align: right" class="form-control invoice-item" name="quantity"/>
|
style="text-align: right" class="form-control invoice-item" name="quantity"/>
|
||||||
</td>
|
</td>
|
||||||
<td style="display:none;" data-bind="visible: $root.invoice_item_taxes.show">
|
<td style="display:none;" data-bind="visible: $root.invoice_item_taxes.show">
|
||||||
{!! Former::select('')
|
{!! Former::select('')
|
||||||
->addOption('', '')
|
->addOption('', '')
|
||||||
->options($taxRateOptions)
|
->options($taxRateOptions)
|
||||||
->data_bind('value: tax1')
|
->data_bind('value: tax1, event:{change:onTax1Change}')
|
||||||
->addClass($account->enable_second_tax_rate ? 'tax-select' : '')
|
->addClass($account->enable_second_tax_rate ? 'tax-select' : '')
|
||||||
->raw() !!}
|
->raw() !!}
|
||||||
<input type="text" data-bind="value: tax_name1, attr: {name: 'invoice_items[' + $index() + '][tax_name1]'}" style="display:none">
|
<input type="text" data-bind="value: tax_name1, attr: {name: 'invoice_items[' + $index() + '][tax_name1]'}" style="display:none">
|
||||||
<input type="text" data-bind="value: tax_rate1, attr: {name: 'invoice_items[' + $index() + '][tax_rate1]'}" style="display:none">
|
<input type="text" data-bind="value: tax_rate1, attr: {name: 'invoice_items[' + $index() + '][tax_rate1]'}" style="display:none">
|
||||||
<div data-bind="visible: $root.invoice().account.enable_second_tax_rate == '1'">
|
<div data-bind="visible: $root.invoice().account.enable_second_tax_rate == '1'">
|
||||||
{!! Former::select('')
|
{!! Former::select('')
|
||||||
->addOption('', '')
|
->addOption('', '')
|
||||||
->options($taxRateOptions)
|
->options($taxRateOptions)
|
||||||
->data_bind('value: tax2')
|
->data_bind('value: tax2, event:{change:onTax2Change}')
|
||||||
->addClass('tax-select')
|
->addClass('tax-select')
|
||||||
->raw() !!}
|
->raw() !!}
|
||||||
</div>
|
</div>
|
||||||
@ -452,7 +452,7 @@
|
|||||||
->addOption('', '')
|
->addOption('', '')
|
||||||
->options($taxRateOptions)
|
->options($taxRateOptions)
|
||||||
->addClass($account->enable_second_tax_rate ? 'tax-select' : '')
|
->addClass($account->enable_second_tax_rate ? 'tax-select' : '')
|
||||||
->data_bind('value: tax1')
|
->data_bind('value: tax1, event:{change:onTax1Change}')
|
||||||
->raw() !!}
|
->raw() !!}
|
||||||
<input type="text" name="tax_name1" data-bind="value: tax_name1" style="display:none">
|
<input type="text" name="tax_name1" data-bind="value: tax_name1" style="display:none">
|
||||||
<input type="text" name="tax_rate1" data-bind="value: tax_rate1" style="display:none">
|
<input type="text" name="tax_rate1" data-bind="value: tax_rate1" style="display:none">
|
||||||
@ -461,7 +461,7 @@
|
|||||||
->addOption('', '')
|
->addOption('', '')
|
||||||
->options($taxRateOptions)
|
->options($taxRateOptions)
|
||||||
->addClass('tax-select')
|
->addClass('tax-select')
|
||||||
->data_bind('value: tax2')
|
->data_bind('value: tax2, event:{change:onTax2Change}')
|
||||||
->raw() !!}
|
->raw() !!}
|
||||||
</div>
|
</div>
|
||||||
<input type="text" name="tax_name2" data-bind="value: tax_name2" style="display:none">
|
<input type="text" name="tax_name2" data-bind="value: tax_name2" style="display:none">
|
||||||
|
@ -179,8 +179,10 @@ function InvoiceModel(data) {
|
|||||||
self.last_sent_date = ko.observable('');
|
self.last_sent_date = ko.observable('');
|
||||||
self.tax_name1 = ko.observable();
|
self.tax_name1 = ko.observable();
|
||||||
self.tax_rate1 = ko.observable();
|
self.tax_rate1 = ko.observable();
|
||||||
|
self.tax_rate1IsInclusive = ko.observable(0);
|
||||||
self.tax_name2 = ko.observable();
|
self.tax_name2 = ko.observable();
|
||||||
self.tax_rate2 = ko.observable();
|
self.tax_rate2 = ko.observable();
|
||||||
|
self.tax_rate2IsInclusive = ko.observable(0);
|
||||||
self.is_recurring = ko.observable(0);
|
self.is_recurring = ko.observable(0);
|
||||||
self.is_quote = ko.observable({{ $entityType == ENTITY_QUOTE ? '1' : '0' }});
|
self.is_quote = ko.observable({{ $entityType == ENTITY_QUOTE ? '1' : '0' }});
|
||||||
self.auto_bill = ko.observable(0);
|
self.auto_bill = ko.observable(0);
|
||||||
@ -268,25 +270,25 @@ function InvoiceModel(data) {
|
|||||||
|
|
||||||
this.tax1 = ko.computed({
|
this.tax1 = ko.computed({
|
||||||
read: function () {
|
read: function () {
|
||||||
return self.tax_rate1() + ' ' + self.tax_name1();
|
return self.tax_rate1IsInclusive() + ' ' + self.tax_rate1() + ' ' + self.tax_name1();
|
||||||
},
|
},
|
||||||
write: function(value) {
|
write: function(value) {
|
||||||
var rate = value.substr(0, value.indexOf(' '));
|
var parts = value.split(' ');
|
||||||
var name = value.substr(value.indexOf(' ') + 1);
|
self.tax_rate1IsInclusive(parts.shift());
|
||||||
self.tax_name1(name);
|
self.tax_rate1(parts.shift());
|
||||||
self.tax_rate1(rate);
|
self.tax_name1(parts.join(' '));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.tax2 = ko.computed({
|
this.tax2 = ko.computed({
|
||||||
read: function () {
|
read: function () {
|
||||||
return self.tax_rate2() + ' ' + self.tax_name2();
|
return self.tax_rate2IsInclusive() + ' ' + self.tax_rate2() + ' ' + self.tax_name2();
|
||||||
},
|
},
|
||||||
write: function(value) {
|
write: function(value) {
|
||||||
var rate = value.substr(0, value.indexOf(' '));
|
var parts = value.split(' ');
|
||||||
var name = value.substr(value.indexOf(' ') + 1);
|
self.tax_rate2IsInclusive(parts.shift());
|
||||||
self.tax_name2(name);
|
self.tax_rate2(parts.shift());
|
||||||
self.tax_rate2(rate);
|
self.tax_name2(parts.join(' '));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -498,6 +500,37 @@ function InvoiceModel(data) {
|
|||||||
self.showResetFooter = function() {
|
self.showResetFooter = function() {
|
||||||
return self.default_footer() && self.invoice_footer() != self.default_footer();
|
return self.default_footer() && self.invoice_footer() != self.default_footer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.applyInclusivTax = function(taxRate) {
|
||||||
|
for (var i=0; i<self.invoice_items().length; i++) {
|
||||||
|
var item = self.invoice_items()[i];
|
||||||
|
item.applyInclusivTax(taxRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onTax1Change = function(obj, event) {
|
||||||
|
if ( ! event.originalEvent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var taxKey = $(event.currentTarget).val();
|
||||||
|
var taxRate = parseFloat(self.tax_rate1());
|
||||||
|
if (taxKey.substr(0, 1) != 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.applyInclusivTax(taxRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onTax2Change = function(obj, event) {
|
||||||
|
if ( ! event.originalEvent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var taxKey = $(event.currentTarget).val();
|
||||||
|
var taxRate = parseFloat(self.tax_rate2());
|
||||||
|
if (taxKey.substr(0, 1) != 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.applyInclusivTax(taxRate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ClientModel(data) {
|
function ClientModel(data) {
|
||||||
@ -666,33 +699,35 @@ function ItemModel(data) {
|
|||||||
self.custom_value2 = ko.observable('');
|
self.custom_value2 = ko.observable('');
|
||||||
self.tax_name1 = ko.observable('');
|
self.tax_name1 = ko.observable('');
|
||||||
self.tax_rate1 = ko.observable(0);
|
self.tax_rate1 = ko.observable(0);
|
||||||
|
self.tax_rate1IsInclusive = ko.observable(0);
|
||||||
self.tax_name2 = ko.observable('');
|
self.tax_name2 = ko.observable('');
|
||||||
self.tax_rate2 = ko.observable(0);
|
self.tax_rate2 = ko.observable(0);
|
||||||
|
self.tax_rate2IsInclusive = ko.observable(0);
|
||||||
self.task_public_id = ko.observable('');
|
self.task_public_id = ko.observable('');
|
||||||
self.expense_public_id = ko.observable('');
|
self.expense_public_id = ko.observable('');
|
||||||
self.actionsVisible = ko.observable(false);
|
self.actionsVisible = ko.observable(false);
|
||||||
|
|
||||||
this.tax1 = ko.computed({
|
this.tax1 = ko.computed({
|
||||||
read: function () {
|
read: function () {
|
||||||
return self.tax_rate1() + ' ' + self.tax_name1();
|
return self.tax_rate1IsInclusive() + ' ' + self.tax_rate1() + ' ' + self.tax_name1();
|
||||||
},
|
},
|
||||||
write: function(value) {
|
write: function(value) {
|
||||||
var rate = value.substr(0, value.indexOf(' '));
|
var parts = value.split(' ');
|
||||||
var name = value.substr(value.indexOf(' ') + 1);
|
self.tax_rate1IsInclusive(parts.shift());
|
||||||
self.tax_name1(name);
|
self.tax_rate1(parts.shift());
|
||||||
self.tax_rate1(rate);
|
self.tax_name1(parts.join(' '));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.tax2 = ko.computed({
|
this.tax2 = ko.computed({
|
||||||
read: function () {
|
read: function () {
|
||||||
return self.tax_rate2() + ' ' + self.tax_name2();
|
return self.tax_rate2IsInclusive() + ' ' + self.tax_rate2() + ' ' + self.tax_name2();
|
||||||
},
|
},
|
||||||
write: function(value) {
|
write: function(value) {
|
||||||
var rate = value.substr(0, value.indexOf(' '));
|
var parts = value.split(' ');
|
||||||
var name = value.substr(value.indexOf(' ') + 1);
|
self.tax_rate2IsInclusive(parts.shift());
|
||||||
self.tax_name2(name);
|
self.tax_rate2(parts.shift());
|
||||||
self.tax_rate2(rate);
|
self.tax_name2(parts.join(' '));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -747,6 +782,34 @@ function ItemModel(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.onSelect = function() {}
|
this.onSelect = function() {}
|
||||||
|
|
||||||
|
self.applyInclusivTax = function(taxRate) {
|
||||||
|
if ( ! taxRate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var cost = self.cost() / (100 + taxRate) * 100;
|
||||||
|
self.cost(roundToTwo(cost));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onTax1Change = function (obj, event) {
|
||||||
|
if (event.originalEvent) {
|
||||||
|
var taxKey = $(event.currentTarget).val();
|
||||||
|
var taxRate = parseFloat(self.tax_rate1());
|
||||||
|
if (taxKey.substr(0, 1) == 1) {
|
||||||
|
self.applyInclusivTax(taxRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onTax2Change = function (obj, event) {
|
||||||
|
if (event.originalEvent) {
|
||||||
|
var taxKey = $(event.currentTarget).val();
|
||||||
|
var taxRate = parseFloat(self.tax_rate2());
|
||||||
|
if (taxKey.substr(0, 1) == 1) {
|
||||||
|
self.applyInclusivTax(taxRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function DocumentModel(data) {
|
function DocumentModel(data) {
|
||||||
@ -838,9 +901,8 @@ ko.bindingHandlers.productTypeahead = {
|
|||||||
}
|
}
|
||||||
@if ($account->invoice_item_taxes)
|
@if ($account->invoice_item_taxes)
|
||||||
if (datum.default_tax_rate) {
|
if (datum.default_tax_rate) {
|
||||||
model.tax_rate1(datum.default_tax_rate.rate);
|
var $select = $(this).parentsUntil('tbody').find('select').first();
|
||||||
model.tax_name1(datum.default_tax_rate.name);
|
$select.val('0 ' + datum.default_tax_rate.rate + ' ' + datum.default_tax_rate.name).trigger('change');
|
||||||
model.tax1(datum.default_tax_rate.rate + ' ' + datum.default_tax_rate.name);
|
|
||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user