diff --git a/app/Http/Controllers/AccountApiController.php b/app/Http/Controllers/AccountApiController.php index bee5c09c7094..39b6cb21c852 100644 --- a/app/Http/Controllers/AccountApiController.php +++ b/app/Http/Controllers/AccountApiController.php @@ -82,7 +82,7 @@ class AccountApiController extends BaseAPIController $updatedAt = $request->updated_at ? date('Y-m-d H:i:s', $request->updated_at) : false; $transformer = new AccountTransformer(null, $request->serializer); - $account->load(array_merge($transformer->getDefaultIncludes(), ['projects.client', 'products.default_tax_rate'])); + $account->load(array_merge($transformer->getDefaultIncludes(), ['projects.client'])); $account = $this->createItem($account, $transformer, 'account'); return $this->response($account); diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 95ca91336c52..7751efcd3f8a 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -487,7 +487,7 @@ class AccountController extends BaseController $data = [ 'account' => Auth::user()->account, 'title' => trans('texts.tax_rates'), - 'taxRates' => TaxRate::scope()->whereIsInclusive(false)->get(['id', 'name', 'rate']), + 'taxRates' => TaxRate::scope()->whereIsInclusive(false)->get(), ]; return View::make('accounts.tax_rates', $data); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 9fc99f4533ce..af75ea136301 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -302,9 +302,8 @@ class InvoiceController extends BaseController return [ 'data' => Input::old('data'), 'account' => Auth::user()->account->load('country'), - 'products' => Product::scope()->with('default_tax_rate')->orderBy('product_key')->get(), + 'products' => Product::scope()->orderBy('product_key')->get(), 'taxRateOptions' => $taxRateOptions, - 'defaultTax' => $account->default_tax_rate, 'currencies' => Cache::get('currencies'), 'sizes' => Cache::get('sizes'), 'invoiceDesigns' => InvoiceDesign::getDesigns(), diff --git a/app/Http/Controllers/OnlinePaymentController.php b/app/Http/Controllers/OnlinePaymentController.php index 163eaf30ca08..bc0b05dea920 100644 --- a/app/Http/Controllers/OnlinePaymentController.php +++ b/app/Http/Controllers/OnlinePaymentController.php @@ -346,8 +346,10 @@ class OnlinePaymentController extends BaseController 'frequency_id' => Input::get('frequency_id'), 'auto_bill_id' => Input::get('auto_bill_id'), 'start_date' => Input::get('start_date', date('Y-m-d')), - 'tax_rate1' => $account->default_tax_rate ? $account->default_tax_rate->rate : 0, - 'tax_name1' => $account->default_tax_rate ? $account->default_tax_rate->name : '', + 'tax_rate1' => $account->tax_rate1, + 'tax_name1' => $account->tax_name1, + 'tax_rate2' => $account->tax_rate2, + 'tax_name2' => $account->tax_name2, 'custom_text_value1' => Input::get('custom_invoice1'), 'custom_text_value2' => Input::get('custom_invoice2'), 'invoice_items' => [[ @@ -355,8 +357,10 @@ class OnlinePaymentController extends BaseController 'notes' => $product->notes, 'cost' => $product->cost, 'qty' => 1, - 'tax_rate1' => $product->default_tax_rate ? $product->default_tax_rate->rate : 0, - 'tax_name1' => $product->default_tax_rate ? $product->default_tax_rate->name : '', + 'tax_rate1' => $account->tax_rate1, + 'tax_name1' => $account->tax_name1, + 'tax_rate2' => $account->tax_rate2, + 'tax_name2' => $account->tax_name2, 'custom_value1' => Input::get('custom_product1') ?: $product->custom_value1, 'custom_value2' => Input::get('custom_product2') ?: $product->custom_value2, ]], diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php index 0661fb3750f1..80ab9c5f73b8 100644 --- a/app/Http/Controllers/ProductController.php +++ b/app/Http/Controllers/ProductController.php @@ -83,7 +83,7 @@ class ProductController extends BaseController $data = [ 'account' => $account, - 'taxRates' => $account->invoice_item_taxes ? TaxRate::scope()->whereIsInclusive(false)->get(['id', 'name', 'rate']) : null, + 'taxRates' => $account->invoice_item_taxes ? TaxRate::scope()->whereIsInclusive(false)->get() : null, 'product' => $product, 'entity' => $product, 'method' => 'PUT', diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php index 0e154c5e0ec6..264b2f7acb27 100644 --- a/app/Http/Controllers/QuoteController.php +++ b/app/Http/Controllers/QuoteController.php @@ -98,9 +98,8 @@ class QuoteController extends BaseController return [ 'entityType' => ENTITY_QUOTE, 'account' => $account, - 'products' => Product::scope()->with('default_tax_rate')->orderBy('product_key')->get(), + 'products' => Product::scope()->orderBy('product_key')->get(), 'taxRateOptions' => $account->present()->taxRateOptions, - 'defaultTax' => $account->default_tax_rate, 'countries' => Cache::get('countries'), 'clients' => Client::scope()->with('contacts', 'country')->orderBy('name')->get(), 'taxRates' => TaxRate::scope()->orderBy('name')->get(), diff --git a/app/Models/Account.php b/app/Models/Account.php index b5b8b4b2d9c6..8ef47d45b74f 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -110,7 +110,10 @@ class Account extends Eloquent 'num_days_reminder3', 'custom_invoice_text_label1', 'custom_invoice_text_label2', - 'default_tax_rate_id', + 'tax_name1', + 'tax_rate1', + 'tax_name2', + 'tax_rate2', 'recurring_hour', 'invoice_number_pattern', 'quote_number_pattern', @@ -366,14 +369,6 @@ class Account extends Eloquent return $this->belongsTo('App\Models\Industry'); } - /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function default_tax_rate() - { - return $this->belongsTo('App\Models\TaxRate'); - } - /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ diff --git a/app/Models/Product.php b/app/Models/Product.php index 6c040b979ca9..ca632d655ab8 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -30,7 +30,10 @@ class Product extends EntityModel 'notes', 'cost', 'qty', - 'default_tax_rate_id', + 'tax_name1', + 'tax_rate1', + 'tax_name2', + 'tax_rate2', 'custom_value1', 'custom_value2', ]; @@ -84,12 +87,4 @@ class Product extends EntityModel { return $this->belongsTo('App\Models\User')->withTrashed(); } - - /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function default_tax_rate() - { - return $this->belongsTo('App\Models\TaxRate'); - } } diff --git a/app/Ninja/Intents/InvoiceIntent.php b/app/Ninja/Intents/InvoiceIntent.php index a6b712c01304..77f8a4d525a6 100644 --- a/app/Ninja/Intents/InvoiceIntent.php +++ b/app/Ninja/Intents/InvoiceIntent.php @@ -83,11 +83,13 @@ class InvoiceIntent extends BaseIntent $item['cost'] = $product->cost; $item['notes'] = $product->notes; + /* if ($taxRate = $product->default_tax_rate) { $item['tax_name1'] = $taxRate->name; $item['tax_rate1'] = $taxRate->rate; } - + */ + $invoiceItems[] = $item; } } diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 505eecadfdb7..965a8c6e95bf 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -655,6 +655,10 @@ class InvoiceRepository extends BaseRepository if ($product && (Auth::user()->can('edit', $product))) { $product->notes = ($task || $expense) ? '' : $item['notes']; $product->cost = $expense ? 0 : $item['cost']; + $product->tax_name1 = $item['tax_name1']; + $product->tax_rate1 = $item['tax_rate1']; + $product->tax_name2 = $item['tax_name2']; + $product->tax_rate2 = $item['tax_rate2']; $product->custom_value1 = isset($item['custom_value1']) ? $item['custom_value1'] : null; $product->custom_value2 = isset($item['custom_value2']) ? $item['custom_value2'] : null; $product->save(); diff --git a/app/Ninja/Repositories/ProductRepository.php b/app/Ninja/Repositories/ProductRepository.php index 41a56b7a728e..49659beddaea 100644 --- a/app/Ninja/Repositories/ProductRepository.php +++ b/app/Ninja/Repositories/ProductRepository.php @@ -23,18 +23,14 @@ class ProductRepository extends BaseRepository public function find($accountId, $filter = null) { $query = DB::table('products') - ->leftJoin('tax_rates', function ($join) { - $join->on('tax_rates.id', '=', 'products.default_tax_rate_id') - ->whereNull('tax_rates.deleted_at'); - }) ->where('products.account_id', '=', $accountId) ->select( 'products.public_id', 'products.product_key', 'products.notes', 'products.cost', - 'tax_rates.name as tax_name', - 'tax_rates.rate as tax_rate', + 'products.tax_name1 as tax_name', + 'products.tax_rate1 as tax_rate', 'products.deleted_at', 'products.is_deleted' ); @@ -82,9 +78,7 @@ class ProductRepository extends BaseRepository $max = SIMILAR_MIN_THRESHOLD; $productId = 0; - $products = Product::scope() - ->with('default_tax_rate') - ->get(); + $products = Product::scope()->get(); foreach ($products as $product) { if (! $product->product_key) { diff --git a/app/Ninja/Transformers/AccountTransformer.php b/app/Ninja/Transformers/AccountTransformer.php index 2effb3b97d40..f9a0f3a6ebdb 100644 --- a/app/Ninja/Transformers/AccountTransformer.php +++ b/app/Ninja/Transformers/AccountTransformer.php @@ -213,7 +213,10 @@ class AccountTransformer extends EntityTransformer 'num_days_reminder3' => $account->num_days_reminder3, 'custom_invoice_text_label1' => $account->custom_invoice_text_label1, 'custom_invoice_text_label2' => $account->custom_invoice_text_label2, - 'default_tax_rate_id' => $account->default_tax_rate_id ? $account->default_tax_rate->public_id : 0, + 'tax_name1' => $account->tax_name1 ?: '', + 'tax_rate1' => (float) $account->tax_rate1, + 'tax_name2' => $account->tax_name2 ?: '', + 'tax_rate2' => (float) $account->tax_rate2, 'recurring_hour' => $account->recurring_hour, 'invoice_number_pattern' => $account->invoice_number_pattern, 'quote_number_pattern' => $account->quote_number_pattern, diff --git a/app/Ninja/Transformers/ProductTransformer.php b/app/Ninja/Transformers/ProductTransformer.php index ceba995c6223..b2c23d595bb8 100644 --- a/app/Ninja/Transformers/ProductTransformer.php +++ b/app/Ninja/Transformers/ProductTransformer.php @@ -15,7 +15,6 @@ class ProductTransformer extends EntityTransformer * @SWG\Property(property="notes", type="string", example="Notes...") * @SWG\Property(property="cost", type="number", format="float", example=10.00) * @SWG\Property(property="qty", type="number", format="float", example=1) - * @SWG\Property(property="default_tax_rate_id", type="integer", example=1) * @SWG\Property(property="updated_at", type="integer", example=1451160233, readOnly=true) * @SWG\Property(property="archived_at", type="integer", example=1451160233, readOnly=true) */ @@ -27,7 +26,10 @@ class ProductTransformer extends EntityTransformer 'notes' => $product->notes, 'cost' => $product->cost, 'qty' => $product->qty, - 'default_tax_rate_id' => $product->default_tax_rate_id ? $product->default_tax_rate->public_id : 0, + 'tax_name1' => $product->tax_name1 ?: '', + 'tax_rate1' => (float) $product->tax_rate1, + 'tax_name2' => $product->tax_name2 ?: '', + 'tax_rate2' => (float) $product->tax_rate2, 'updated_at' => $this->getTimestamp($product->updated_at), 'archived_at' => $this->getTimestamp($product->deleted_at), ]); diff --git a/database/migrations/2017_05_16_101715_add_default_note_to_client.php b/database/migrations/2017_05_16_101715_add_default_note_to_client.php index f7d810889f6f..841550b53448 100644 --- a/database/migrations/2017_05_16_101715_add_default_note_to_client.php +++ b/database/migrations/2017_05_16_101715_add_default_note_to_client.php @@ -23,6 +23,41 @@ class AddDefaultNoteToClient extends Migration Schema::table('payments', function ($table) { $table->text('private_notes')->nullable(); }); + + Schema::table('accounts', function ($table) { + $table->string('tax_name1')->nullable(); + $table->decimal('tax_rate1', 13, 3); + $table->string('tax_name2')->nullable(); + $table->decimal('tax_rate2', 13, 3); + }); + + Schema::table('products', function ($table) { + $table->string('tax_name1')->nullable(); + $table->decimal('tax_rate1', 13, 3); + $table->string('tax_name2')->nullable(); + $table->decimal('tax_rate2', 13, 3); + }); + + DB::statement('update products + left join tax_rates on tax_rates.id = products.default_tax_rate_id + set products.tax_name1 = tax_rates.name, products.tax_rate1 = tax_rates.rate'); + + DB::statement('update accounts + left join tax_rates on tax_rates.id = accounts.default_tax_rate_id + set accounts.tax_name1 = tax_rates.name, accounts.tax_rate1 = tax_rates.rate'); + + if (Schema::hasColumn('accounts', 'default_tax_rate_id')) { + Schema::table('accounts', function ($table) { + $table->dropColumn('default_tax_rate_id'); + } + }); + + if (Schema::hasColumn('products', 'default_tax_rate_id')) { + Schema::table('products', function ($table) { + $table->dropColumn('default_tax_rate_id'); + } + }); + } /** @@ -43,5 +78,19 @@ class AddDefaultNoteToClient extends Migration Schema::table('payments', function ($table) { $table->dropColumn('private_notes'); }); + + Schema::table('accounts', function ($table) { + $table->dropColumn('tax_name1'); + $table->dropColumn('tax_rate1'); + $table->dropColumn('tax_name2'); + $table->dropColumn('tax_rate2'); + }); + + Schema::table('products', function ($table) { + $table->dropColumn('tax_name1'); + $table->dropColumn('tax_rate1'); + $table->dropColumn('tax_name2'); + $table->dropColumn('tax_rate2'); + }); } } diff --git a/resources/views/accounts/product.blade.php b/resources/views/accounts/product.blade.php index 8627e9a537aa..082c99396382 100644 --- a/resources/views/accounts/product.blade.php +++ b/resources/views/accounts/product.blade.php @@ -33,12 +33,7 @@ {!! Former::text('cost') !!} - @if ($account->invoice_item_taxes) - {!! Former::select('default_tax_rate_id') - ->addOption('', '') - ->label(trans('texts.tax_rate')) - ->fromQuery($taxRates, function($model) { return $model->name . ': ' . $model->rate . '%'; }, 'id') !!} - @endif + @include('partials.tax_rates') diff --git a/resources/views/accounts/tax_rates.blade.php b/resources/views/accounts/tax_rates.blade.php index 31ba79fadd35..e850f462f6f3 100644 --- a/resources/views/accounts/tax_rates.blade.php +++ b/resources/views/accounts/tax_rates.blade.php @@ -47,11 +47,7 @@   - {!! Former::select('default_tax_rate_id') - ->style('max-width: 250px') - ->addOption('', '') - ->fromQuery($taxRates, function($model) { return $model->name . ': ' . $model->rate . '%'; }, 'id') !!} - + @include('partials.tax_rates')   {!! Former::actions( Button::success(trans('texts.save'))->submit()->appendIcon(Icon::create('floppy-disk')) ) !!} diff --git a/resources/views/expenses/edit.blade.php b/resources/views/expenses/edit.blade.php index 524b3c79ee7e..d5901e47c651 100644 --- a/resources/views/expenses/edit.blade.php +++ b/resources/views/expenses/edit.blade.php @@ -152,35 +152,13 @@ ->label(' ') ->value(1) !!} @endif - -
-
- {!! Former::select('tax_select1') - ->addOption('','') - ->label(trans('texts.tax_rate')) - ->onchange('taxSelectChange(event)') - ->fromQuery($taxRates) !!} - -
- {!! Former::input('tax_rate1') !!} - {!! Former::input('tax_name1') !!} -
- -
- {!! Former::select('tax_select2') - ->addOption('','') - ->label(trans('texts.tax_rate')) - ->onchange('taxSelectChange(event)') - ->fromQuery($taxRates) !!} - -
- {!! Former::input('tax_rate2') !!} - {!! Former::input('tax_name2') !!} -
-
-
@endif +
+
+ @include('partials.tax_rates') +
+ @if ($account->hasFeature(FEATURE_DOCUMENTS)) {!! Former::checkbox('invoice_documents') ->text(trans('texts.add_documents_to_invoice')) @@ -259,7 +237,6 @@ var vendors = {!! $vendors !!}; var clients = {!! $clients !!}; var categories = {!! $categories !!}; - var taxRates = {!! $taxRates !!}; var clientMap = {}; var vendorMap = {}; @@ -355,9 +332,6 @@ onClientChange(); }); - setTaxSelect(1); - setTaxSelect(2); - @if ($data) // this means we failed so we'll reload the previous state window.model = new ViewModel({!! $data !!}); @@ -594,38 +568,6 @@ 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); - } - } - function onInvoiceDocumentsChange() { if (isStorageSupported()) { diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php index 775423e1d896..f30bc674ec07 100644 --- a/resources/views/invoices/edit.blade.php +++ b/resources/views/invoices/edit.blade.php @@ -908,10 +908,15 @@ model.invoice().addItem(); // add blank item @else // set the default account tax rate - @if ($account->invoice_taxes && ! empty($defaultTax)) - var defaultTax = {!! $defaultTax->toJson() !!}; - model.invoice().tax_rate1(defaultTax.rate); - model.invoice().tax_name1(defaultTax.name); + @if ($account->invoice_taxes) + @if (! empty($account->tax_name1)) + model.invoice().tax_rate1("{{ $account->tax_rate1 }}"); + model.invoice().tax_name1("{{ $account->tax_name1 }}"); + @endif + @if (! empty($account->tax_name2)) + model.invoice().tax_rate2("{{ $account->tax_rate2 }}"); + model.invoice().tax_name2("{{ $account->tax_name2 }}"); + @endif @endif @endif diff --git a/resources/views/invoices/knockout.blade.php b/resources/views/invoices/knockout.blade.php index 4afe7107c99d..d5eca7b67f69 100644 --- a/resources/views/invoices/knockout.blade.php +++ b/resources/views/invoices/knockout.blade.php @@ -944,9 +944,13 @@ ko.bindingHandlers.productTypeahead = { model.qty(1); } @if ($account->invoice_item_taxes) - if (datum.default_tax_rate) { + if (datum.tax_name1) { var $select = $(this).parentsUntil('tbody').find('select').first(); - $select.val('0 ' + datum.default_tax_rate.rate + ' ' + datum.default_tax_rate.name).trigger('change'); + $select.val('0 ' + datum.tax_rate1 + ' ' + datum.tax_name1).trigger('change'); + } + if (datum.tax_name2) { + var $select = $(this).parentsUntil('tbody').find('select').last(); + $select.val('0 ' + datum.tax_rate2 + ' ' + datum.tax_name2).trigger('change'); } @endif @if (Auth::user()->isPro() && $account->custom_invoice_item_label1) diff --git a/resources/views/partials/tax_rates.blade.php b/resources/views/partials/tax_rates.blade.php new file mode 100644 index 000000000000..9e1d546f802b --- /dev/null +++ b/resources/views/partials/tax_rates.blade.php @@ -0,0 +1,69 @@ +@if ($account->invoice_item_taxes) + {!! Former::select('tax_select1') + ->addOption('','') + ->label(trans('texts.tax_rate')) + ->onchange('taxSelectChange(event)') + ->fromQuery($taxRates) !!} + +
+ {!! Former::input('tax_rate1') !!} + {!! Former::input('tax_name1') !!} +
+ +
+ {!! Former::select('tax_select2') + ->addOption('','') + ->label(trans('texts.tax_rate')) + ->onchange('taxSelectChange(event)') + ->fromQuery($taxRates) !!} + +
+ {!! Former::input('tax_rate2') !!} + {!! Former::input('tax_name2') !!} +
+
+@endif + + +