diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php index 46f40b0bf251..28c7033154bf 100644 --- a/app/Http/Controllers/InvoiceApiController.php +++ b/app/Http/Controllers/InvoiceApiController.php @@ -258,10 +258,11 @@ class InvoiceApiController extends BaseAPIController // initialize the line items if (isset($data['product_key']) || isset($data['cost']) || isset($data['notes']) || isset($data['qty'])) { $data['invoice_items'] = [self::prepareItem($data)]; - // make sure the tax isn't applied twice (for the invoice and the line item) - unset($data['invoice_items'][0]['tax_name']); - unset($data['invoice_items'][0]['tax_rate']); + unset($data['invoice_items'][0]['tax_name1']); + unset($data['invoice_items'][0]['tax_rate1']); + unset($data['invoice_items'][0]['tax_name2']); + unset($data['invoice_items'][0]['tax_rate2']); } else { foreach ($data['invoice_items'] as $index => $item) { $data['invoice_items'][$index] = self::prepareItem($item); diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index f6ea28e31c9c..bdf546395c34 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -25,6 +25,13 @@ class Invoice extends EntityModel implements BalanceAffecting protected $presenter = 'App\Ninja\Presenters\InvoicePresenter'; protected $dates = ['deleted_at']; + protected $fillable = [ + 'tax_name1', + 'tax_rate1', + 'tax_name2', + 'tax_rate2', + ]; + protected $casts = [ 'is_recurring' => 'boolean', 'has_tasks' => 'boolean', @@ -394,8 +401,10 @@ class Invoice extends EntityModel implements BalanceAffecting 'documents', 'expenses', 'client', - 'tax_name', - 'tax_rate', + 'tax_name1', + 'tax_rate1', + 'tax_name2', + 'tax_rate2', 'account', 'invoice_design', 'invoice_design_id', @@ -476,8 +485,10 @@ class Invoice extends EntityModel implements BalanceAffecting 'custom_value2', 'cost', 'qty', - 'tax_name', - 'tax_rate', + 'tax_name1', + 'tax_rate1', + 'tax_name2', + 'tax_rate2', ]); } @@ -843,54 +854,68 @@ class Invoice extends EntityModel implements BalanceAffecting return $total; } + // if $calculatePaid is true we'll loop through each payment to + // determine the sum, otherwise we'll use the cached paid_to_date amount public function getTaxes($calculatePaid = false) { $taxes = []; $taxable = $this->getTaxable(); - - if ($this->tax_rate && $this->tax_name) { - $taxAmount = $taxable * ($this->tax_rate / 100); - $taxAmount = round($taxAmount, 2); + $paidAmount = $this->getAmountPaid($calculatePaid); + + if ($this->tax_name1) { + $invoiceTaxAmount = round($taxable * ($this->tax_rate1 / 100), 2); + $invoicePaidAmount = $this->amount && $invoiceTaxAmount ? ($paidAmount / $this->amount * $invoiceTaxAmount) : 0; + $this->calculateTax($taxes, $this->tax_name1, $this->tax_rate1, $invoiceTaxAmount, $invoicePaidAmount); + } - if ($taxAmount) { - $taxes[$this->tax_rate . ' ' . $this->tax_name] = [ - 'name' => $this->tax_name, - 'rate' => $this->tax_rate+0, - 'amount' => $taxAmount, - 'paid' => round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2) - ]; - } + if ($this->tax_name2) { + $invoiceTaxAmount = round($taxable * ($this->tax_rate2 / 100), 2); + $invoicePaidAmount = $this->amount && $invoiceTaxAmount ? ($paidAmount / $this->amount * $invoiceTaxAmount) : 0; + $this->calculateTax($taxes, $this->tax_name2, $this->tax_rate2, $invoiceTaxAmount, $invoicePaidAmount); } foreach ($this->invoice_items as $invoiceItem) { - if ( ! $invoiceItem->tax_rate || ! $invoiceItem->tax_name) { - continue; + $itemTaxAmount = $this->getItemTaxable($invoiceItem, $taxable); + + if ($invoiceItem->tax_name1) { + $itemTaxAmount = round($taxable * ($invoiceItem->tax_rate1 / 100), 2); + $itemPaidAmount = $this->amount && $itemTaxAmount ? ($paidAmount / $this->amount * $itemTaxAmount) : 0; + $this->calculateTax($taxes, $invoiceItem->tax_name1, $invoiceItem->tax_rate1, $itemTaxAmount, $itemPaidAmount); } - $taxAmount = $this->getItemTaxable($invoiceItem, $taxable); - $taxAmount = $taxable * ($invoiceItem->tax_rate / 100); - $taxAmount = round($taxAmount, 2); - - if ($taxAmount) { - $key = $invoiceItem->tax_rate . ' ' . $invoiceItem->tax_name; - - if ( ! isset($taxes[$key])) { - $taxes[$key] = [ - 'amount' => 0, - 'paid' => 0 - ]; - } - - $taxes[$key]['amount'] += $taxAmount; - $taxes[$key]['paid'] += $this->amount && $taxAmount ? round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2) : 0; - $taxes[$key]['name'] = $invoiceItem->tax_name; - $taxes[$key]['rate'] = $invoiceItem->tax_rate+0; + if ($invoiceItem->tax_name2) { + $itemTaxAmount = round($taxable * ($invoiceItem->tax_rate2 / 100), 2); + $itemPaidAmount = $this->amount && $itemTaxAmount ? ($paidAmount / $this->amount * $itemTaxAmount) : 0; + $this->calculateTax($taxes, $invoiceItem->tax_name2, $invoiceItem->tax_rate2, $itemTaxAmount, $itemPaidAmount); } } - + return $taxes; } + private function calculateTax(&$taxes, $name, $rate, $amount, $paid) + { + if ( ! $amount) { + return; + } + + $amount = round($amount, 2); + $paid = round($paid, 2); + $key = $rate . ' ' . $name; + + if ( ! isset($taxes[$key])) { + $taxes[$key] = [ + 'name' => $name, + 'rate' => $rate+0, + 'amount' => 0, + 'paid' => 0 + ]; + } + + $taxes[$key]['amount'] += $amount; + $taxes[$key]['paid'] += $paid; + } + public function hasDocuments(){ if(count($this->documents))return true; return $this->hasExpenseDocuments(); diff --git a/app/Models/InvoiceItem.php b/app/Models/InvoiceItem.php index b7b3c8ffc8e9..d3981c931c62 100644 --- a/app/Models/InvoiceItem.php +++ b/app/Models/InvoiceItem.php @@ -7,6 +7,13 @@ class InvoiceItem extends EntityModel use SoftDeletes; protected $dates = ['deleted_at']; + protected $fillable = [ + 'tax_name1', + 'tax_rate1', + 'tax_name2', + 'tax_rate2', + ]; + public function invoice() { return $this->belongsTo('App\Models\Invoice'); diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index f78815c27e7d..0751a7ac0c07 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -221,6 +221,8 @@ class InvoiceRepository extends BaseRepository $invoice = Invoice::scope($publicId)->firstOrFail(); } + $invoice->fill($data); + if ((isset($data['set_default_terms']) && $data['set_default_terms']) || (isset($data['set_default_footer']) && $data['set_default_footer'])) { if (isset($data['set_default_terms']) && $data['set_default_terms']) { @@ -297,12 +299,10 @@ class InvoiceRepository extends BaseRepository $invoice->invoice_design_id = isset($data['invoice_design_id']) ? $data['invoice_design_id'] : $account->invoice_design_id; - if (isset($data['tax_name']) && isset($data['tax_rate']) && $data['tax_name']) { - $invoice->tax_rate = Utils::parseFloat($data['tax_rate']); - $invoice->tax_name = trim($data['tax_name']); - } else { - $invoice->tax_rate = 0; - $invoice->tax_name = ''; + // provide backwards compatability + if (isset($data['tax_name']) && isset($data['tax_rate'])) { + $data['tax_name1'] = $data['tax_name']; + $data['tax_rate1'] = $data['tax_rate']; } $total = 0; @@ -323,20 +323,24 @@ class InvoiceRepository extends BaseRepository foreach ($data['invoice_items'] as $item) { $item = (array) $item; - if (isset($item['tax_rate']) && Utils::parseFloat($item['tax_rate']) > 0) { - $invoiceItemCost = round(Utils::parseFloat($item['cost']), 2); - $invoiceItemQty = round(Utils::parseFloat($item['qty']), 2); - $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate']); - $lineTotal = $invoiceItemCost * $invoiceItemQty; + $invoiceItemCost = round(Utils::parseFloat($item['cost']), 2); + $invoiceItemQty = round(Utils::parseFloat($item['qty']), 2); + $lineTotal = $invoiceItemCost * $invoiceItemQty; - if ($invoice->discount > 0) { - if ($invoice->is_amount_discount) { - $lineTotal -= round(($lineTotal/$total) * $invoice->discount, 2); - } else { - $lineTotal -= round($lineTotal * ($invoice->discount/100), 2); - } + if ($invoice->discount > 0) { + if ($invoice->is_amount_discount) { + $lineTotal -= round(($lineTotal/$total) * $invoice->discount, 2); + } else { + $lineTotal -= round($lineTotal * ($invoice->discount/100), 2); } + } + if (isset($item['tax_rate1']) && Utils::parseFloat($item['tax_rate1']) > 0) { + $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate1']); + $itemTax += round($lineTotal * $invoiceItemTaxRate / 100, 2); + } + if (isset($item['tax_rate2']) && Utils::parseFloat($item['tax_rate2']) > 0) { + $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate2']); $itemTax += round($lineTotal * $invoiceItemTaxRate / 100, 2); } } @@ -378,8 +382,9 @@ class InvoiceRepository extends BaseRepository $total += $invoice->custom_value2; } - $total += $total * $invoice->tax_rate / 100; - $total = round($total, 2); + $taxAmount1 = round($total * $invoice->tax_rate1 / 100, 2); + $taxAmount2 = round($total * $invoice->tax_rate2 / 100, 2); + $total = round($total + $taxAmount1 + $taxAmount2, 2); $total += $itemTax; // custom fields not charged taxes @@ -502,7 +507,7 @@ class InvoiceRepository extends BaseRepository $invoiceItem->notes = trim($invoice->is_recurring ? $item['notes'] : Utils::processVariables($item['notes'])); $invoiceItem->cost = Utils::parseFloat($item['cost']); $invoiceItem->qty = Utils::parseFloat($item['qty']); - $invoiceItem->tax_rate = 0; + //$invoiceItem->tax_rate = 0; if (isset($item['custom_value1'])) { $invoiceItem->custom_value1 = $item['custom_value1']; @@ -511,11 +516,14 @@ class InvoiceRepository extends BaseRepository $invoiceItem->custom_value2 = $item['custom_value2']; } - if (isset($item['tax_rate']) && isset($item['tax_name']) && $item['tax_name']) { - $invoiceItem['tax_rate'] = Utils::parseFloat($item['tax_rate']); - $invoiceItem['tax_name'] = trim($item['tax_name']); + // provide backwards compatability + if (isset($item['tax_name']) && isset($item['tax_rate'])) { + $item['tax_name1'] = $item['tax_name']; + $item['tax_rate1'] = $item['tax_rate']; } + $invoiceItem->fill($item); + $invoice->invoice_items()->save($invoiceItem); } @@ -562,8 +570,10 @@ class InvoiceRepository extends BaseRepository 'invoice_footer', 'public_notes', 'invoice_design_id', - 'tax_name', - 'tax_rate', + 'tax_name1', + 'tax_rate1', + 'tax_name2', + 'tax_rate2', 'amount', 'is_quote', 'custom_value1', @@ -597,8 +607,11 @@ class InvoiceRepository extends BaseRepository 'notes', 'cost', 'qty', - 'tax_name', - 'tax_rate', ] as $field) { + 'tax_name1', + 'tax_rate1', + 'tax_name2', + 'tax_rate2', + ] as $field) { $cloneItem->$field = $item->$field; } @@ -689,8 +702,10 @@ class InvoiceRepository extends BaseRepository $invoice->public_notes = Utils::processVariables($recurInvoice->public_notes); $invoice->terms = Utils::processVariables($recurInvoice->terms); $invoice->invoice_footer = Utils::processVariables($recurInvoice->invoice_footer); - $invoice->tax_name = $recurInvoice->tax_name; - $invoice->tax_rate = $recurInvoice->tax_rate; + $invoice->tax_name1 = $recurInvoice->tax_name1; + $invoice->tax_rate1 = $recurInvoice->tax_rate1; + $invoice->tax_name2 = $recurInvoice->tax_name2; + $invoice->tax_rate2 = $recurInvoice->tax_rate2; $invoice->invoice_design_id = $recurInvoice->invoice_design_id; $invoice->custom_value1 = $recurInvoice->custom_value1 ?: 0; $invoice->custom_value2 = $recurInvoice->custom_value2 ?: 0; @@ -709,8 +724,10 @@ class InvoiceRepository extends BaseRepository $item->cost = $recurItem->cost; $item->notes = Utils::processVariables($recurItem->notes); $item->product_key = Utils::processVariables($recurItem->product_key); - $item->tax_name = $recurItem->tax_name; - $item->tax_rate = $recurItem->tax_rate; + $item->tax_name1 = $recurItem->tax_name1; + $item->tax_rate1 = $recurItem->tax_rate1; + $item->tax_name2 = $recurItem->tax_name2; + $item->tax_rate2 = $recurItem->tax_rate2; $invoice->invoice_items()->save($item); } diff --git a/app/Ninja/Transformers/InvoiceItemTransformer.php b/app/Ninja/Transformers/InvoiceItemTransformer.php index 66d9fe137dd8..ab95b9cfd3d5 100644 --- a/app/Ninja/Transformers/InvoiceItemTransformer.php +++ b/app/Ninja/Transformers/InvoiceItemTransformer.php @@ -19,8 +19,10 @@ class InvoiceItemTransformer extends EntityTransformer 'notes' => $item->notes, 'cost' => (float) $item->cost, 'qty' => (float) $item->qty, - 'tax_name' => $item->tax_name, - 'tax_rate' => (float) $item->tax_rate + 'tax_name1' => $item->tax_name1, + 'tax_rate1' => (float) $item->tax_rate1, + 'tax_name2' => $item->tax_name2, + 'tax_rate2' => (float) $item->tax_rate2, ]; } } \ No newline at end of file diff --git a/app/Ninja/Transformers/InvoiceTransformer.php b/app/Ninja/Transformers/InvoiceTransformer.php index b67635386d8e..81999a2a6481 100644 --- a/app/Ninja/Transformers/InvoiceTransformer.php +++ b/app/Ninja/Transformers/InvoiceTransformer.php @@ -87,8 +87,10 @@ class InvoiceTransformer extends EntityTransformer 'end_date' => $invoice->end_date, 'last_sent_date' => $invoice->last_sent_date, 'recurring_invoice_id' => (int) $invoice->recurring_invoice_id, - 'tax_name' => $invoice->tax_name, - 'tax_rate' => (float) $invoice->tax_rate, + 'tax_name1' => $invoice->tax_name1, + 'tax_rate1' => (float) $invoice->tax_rate1, + 'tax_name2' => $invoice->tax_name2, + 'tax_rate2' => (float) $invoice->tax_rate2, 'amount' => (float) $invoice->amount, 'balance' => (float) $invoice->balance, 'is_amount_discount' => (bool) $invoice->is_amount_discount, diff --git a/composer.json b/composer.json index 3ac3e3ba0e89..a461c1313a64 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "turbo124/laravel-push-notification": "dev-laravel5", + "turbo124/laravel-push-notification": "dev-laravel5", "omnipay/mollie": "dev-master#22956c1a62a9662afa5f5d119723b413770ac525", "omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248", "omnipay/gocardless": "dev-master", diff --git a/database/migrations/2016_03_23_215049_support_multiple_tax_rates.php b/database/migrations/2016_03_23_215049_support_multiple_tax_rates.php index f9b9fd22180a..fce65c240ea7 100644 --- a/database/migrations/2016_03_23_215049_support_multiple_tax_rates.php +++ b/database/migrations/2016_03_23_215049_support_multiple_tax_rates.php @@ -14,10 +14,24 @@ class SupportMultipleTaxRates extends Migration { Schema::table('invoices', function($table) { $table->decimal('tax_rate', 13, 3)->change(); - }); + }); Schema::table('invoice_items', function($table) { $table->decimal('tax_rate', 13, 3)->change(); + }); + + Schema::table('invoices', function($table) { + $table->renameColumn('tax_rate', 'tax_rate1'); + $table->renameColumn('tax_name', 'tax_name1'); + $table->string('tax_name2')->nullable(); + $table->decimal('tax_rate2', 13, 3); + }); + + Schema::table('invoice_items', function($table) { + $table->renameColumn('tax_rate', 'tax_rate1'); + $table->renameColumn('tax_name', 'tax_name1'); + $table->string('tax_name2')->nullable(); + $table->decimal('tax_rate2', 13, 3); }); } /** @@ -28,11 +42,19 @@ class SupportMultipleTaxRates extends Migration public function down() { Schema::table('invoices', function($table) { - $table->decimal('tax_rate', 13, 2)->change(); + $table->decimal('tax_rate1', 13, 2)->change(); + $table->renameColumn('tax_rate1', 'tax_rate'); + $table->renameColumn('tax_name1', 'tax_name'); + $table->dropColumn('tax_name2'); + $table->dropColumn('tax_rate2'); }); Schema::table('invoice_items', function($table) { - $table->decimal('tax_rate', 13, 2)->change(); + $table->decimal('tax_rate1', 13, 2)->change(); + $table->renameColumn('tax_rate1', 'tax_rate'); + $table->renameColumn('tax_name1', 'tax_name'); + $table->dropColumn('tax_name2'); + $table->dropColumn('tax_rate2'); }); } } \ No newline at end of file diff --git a/public/built.js b/public/built.js index 4b8b246ae257..ad547c62ab7b 100644 --- a/public/built.js +++ b/public/built.js @@ -30497,8 +30497,10 @@ function calculateAmounts(invoice) { for (var i=0; i @stop @@ -204,7 +209,7 @@ @endif {{ $invoiceLabels['unit_cost'] }} {{ $invoiceLabels['quantity'] }} - {{ trans('texts.tax') }} + {{ trans('texts.tax') }} {{ trans('texts.line_total') }} @@ -246,10 +251,19 @@ {!! Former::select('') ->addOption('', '') ->options($taxRateOptions) - ->data_bind('value: tax') + ->data_bind('value: tax1') + ->addClass('tax-select') ->raw() !!} - - + + + {!! Former::select('') + ->addOption('', '') + ->options($taxRateOptions) + ->data_bind('value: tax2') + ->addClass('tax-select') + ->raw() !!} + +
@@ -387,10 +401,19 @@ {!! Former::select('') ->addOption('', '') ->options($taxRateOptions) - ->data_bind('value: tax') + ->addClass('tax-select') + ->data_bind('value: tax1') ->raw() !!} - - + + + {!! Former::select('') + ->addOption('', '') + ->options($taxRateOptions) + ->addClass('tax-select') + ->data_bind('value: tax2') + ->raw() !!} + + @@ -770,8 +793,8 @@ // set the default account tax rate @if ($account->invoice_taxes && ! empty($defaultTax)) var defaultTax = {!! $defaultTax !!}; - model.invoice().tax_rate(defaultTax.rate); - model.invoice().tax_name(defaultTax.name); + model.invoice().tax_rate1(defaultTax.rate); + model.invoice().tax_name1(defaultTax.name); @endif @endif diff --git a/resources/views/invoices/knockout.blade.php b/resources/views/invoices/knockout.blade.php index 1769a6e7d100..114c60d1677e 100644 --- a/resources/views/invoices/knockout.blade.php +++ b/resources/views/invoices/knockout.blade.php @@ -52,10 +52,11 @@ function ViewModel(data) { } self.invoice_taxes.show = ko.computed(function() { - if (self.invoice_taxes()) { + if (self.invoice().tax_name1() || self.invoice().tax_name2()) { return true; } - return false; + + return self.invoice_taxes() && {{ count($taxRateOptions) ? 'true' : 'false' }}; }); self.invoice_item_taxes.show = ko.computed(function() { @@ -64,7 +65,7 @@ function ViewModel(data) { } for (var i=0; i 0) { + if (item.tax_name1() || item.tax_name2()) { return true; } } @@ -175,8 +176,10 @@ function InvoiceModel(data) { self.start_date = ko.observable(''); self.end_date = ko.observable(''); self.last_sent_date = ko.observable(''); - self.tax_name = ko.observable(); - self.tax_rate = ko.observable(); + self.tax_name1 = ko.observable(); + self.tax_rate1 = ko.observable(); + self.tax_name2 = ko.observable(); + self.tax_rate2 = ko.observable(); self.is_recurring = ko.observable(0); self.is_quote = ko.observable({{ $entityType == ENTITY_QUOTE ? '1' : '0' }}); self.auto_bill = ko.observable(); @@ -258,15 +261,27 @@ function InvoiceModel(data) { return self.has_tasks() ? invoiceLabels['rate'] : invoiceLabels['unit_cost']; }, this); - this.tax = ko.computed({ + this.tax1 = ko.computed({ read: function () { - return self.tax_rate() + ' ' + self.tax_name(); + return self.tax_rate1() + ' ' + self.tax_name1(); }, write: function(value) { var rate = value.substr(0, value.indexOf(' ')); var name = value.substr(value.indexOf(' ') + 1); - self.tax_name(name); - self.tax_rate(rate); + self.tax_name1(name); + self.tax_rate1(rate); + } + }) + + this.tax2 = ko.computed({ + read: function () { + return self.tax_rate2() + ' ' + self.tax_name2(); + }, + write: function(value) { + var rate = value.substr(0, value.indexOf(' ')); + var name = value.substr(value.indexOf(' ') + 1); + self.tax_name2(name); + self.tax_rate2(rate); } }) @@ -359,15 +374,13 @@ function InvoiceModel(data) { total = NINJA.parseFloat(total) + customValue2; } - var taxRate = parseFloat(self.tax_rate()); - //if (taxRate > 0) { - // var tax = roundToTwo(total * (taxRate/100)); - // return self.formatMoney(tax); - //} else { - // return self.formatMoney(0); - //} - var tax = roundToTwo(total * (taxRate/100)); - return self.formatMoney(tax); + var taxRate1 = parseFloat(self.tax_rate1()); + var tax1 = roundToTwo(total * (taxRate1/100)); + + var taxRate2 = parseFloat(self.tax_rate2()); + var tax2 = roundToTwo(total * (taxRate2/100)); + + return self.formatMoney(tax1 + tax2); }); self.totals.itemTaxes = ko.computed(function() { @@ -383,13 +396,24 @@ function InvoiceModel(data) { lineTotal -= roundToTwo(lineTotal * (self.discount()/100)); } } - var taxAmount = roundToTwo(lineTotal * item.tax_rate() / 100); + + var taxAmount = roundToTwo(lineTotal * item.tax_rate1() / 100); if (taxAmount) { - var key = item.tax_name() + item.tax_rate(); + var key = item.tax_name1() + item.tax_rate1(); if (taxes.hasOwnProperty(key)) { taxes[key].amount += taxAmount; } else { - taxes[key] = {name:item.tax_name(), rate:item.tax_rate(), amount:taxAmount}; + taxes[key] = {name:item.tax_name1(), rate:item.tax_rate1(), amount:taxAmount}; + } + } + + var taxAmount = roundToTwo(lineTotal * item.tax_rate2() / 100); + if (taxAmount) { + var key = item.tax_name2() + item.tax_rate2(); + if (taxes.hasOwnProperty(key)) { + taxes[key].amount += taxAmount; + } else { + taxes[key] = {name:item.tax_name2(), rate:item.tax_rate2(), amount:taxAmount}; } } } @@ -455,8 +479,9 @@ function InvoiceModel(data) { total = NINJA.parseFloat(total) + customValue2; } - var taxRate = parseFloat(self.tax_rate()); - total = NINJA.parseFloat(total) + roundToTwo(total * (taxRate/100)); + var taxAmount1 = roundToTwo(total * (parseFloat(self.tax_rate1())/100)); + var taxAmount2 = roundToTwo(total * (parseFloat(self.tax_rate2())/100)); + total = NINJA.parseFloat(total) + taxAmount1 + taxAmount2; total = roundToTwo(total); var taxes = self.totals.itemTaxes(); @@ -641,21 +666,35 @@ function ItemModel(data) { self.qty = ko.observable(0); self.custom_value1 = ko.observable(''); self.custom_value2 = ko.observable(''); - self.tax_name = ko.observable(''); - self.tax_rate = ko.observable(0); + self.tax_name1 = ko.observable(''); + self.tax_rate1 = ko.observable(0); + self.tax_name2 = ko.observable(''); + self.tax_rate2 = ko.observable(0); self.task_public_id = ko.observable(''); self.expense_public_id = ko.observable(''); self.actionsVisible = ko.observable(false); - this.tax = ko.computed({ + this.tax1 = ko.computed({ read: function () { - return self.tax_rate() + ' ' + self.tax_name(); + return self.tax_rate1() + ' ' + self.tax_name1(); }, write: function(value) { var rate = value.substr(0, value.indexOf(' ')); var name = value.substr(value.indexOf(' ') + 1); - self.tax_name(name); - self.tax_rate(rate); + self.tax_name1(name); + self.tax_rate1(rate); + } + }) + + this.tax2 = ko.computed({ + read: function () { + return self.tax_rate2() + ' ' + self.tax_name2(); + }, + write: function(value) { + var rate = value.substr(0, value.indexOf(' ')); + var name = value.substr(value.indexOf(' ') + 1); + self.tax_name2(name); + self.tax_rate2(rate); } }) @@ -794,9 +833,9 @@ ko.bindingHandlers.typeahead = { } @if ($account->invoice_item_taxes) if (datum.default_tax_rate) { - model.tax_rate(datum.default_tax_rate.rate); - model.tax_name(datum.default_tax_rate.name); - model.tax(datum.default_tax_rate.rate + ' ' + datum.default_tax_rate.name); + model.tax_rate1(datum.default_tax_rate.rate); + model.tax_name1(datum.default_tax_rate.name); + model.tax1(datum.default_tax_rate.rate + ' ' + datum.default_tax_rate.name); } @endif @endif