mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-08 11:14:31 -04:00
Reworking taxes
This commit is contained in:
parent
3e9802502c
commit
f91f32323f
@ -194,7 +194,7 @@ class InvoiceController extends BaseController
|
|||||||
'isRecurring' => $invoice->is_recurring,
|
'isRecurring' => $invoice->is_recurring,
|
||||||
'actions' => $actions,
|
'actions' => $actions,
|
||||||
'lastSent' => $lastSent);
|
'lastSent' => $lastSent);
|
||||||
$data = array_merge($data, self::getViewModel());
|
$data = array_merge($data, self::getViewModel($invoice));
|
||||||
|
|
||||||
if ($clone) {
|
if ($clone) {
|
||||||
$data['formIsChanged'] = true;
|
$data['formIsChanged'] = true;
|
||||||
@ -261,7 +261,7 @@ class InvoiceController extends BaseController
|
|||||||
'url' => 'invoices',
|
'url' => 'invoices',
|
||||||
'title' => trans('texts.new_invoice'),
|
'title' => trans('texts.new_invoice'),
|
||||||
];
|
];
|
||||||
$data = array_merge($data, self::getViewModel());
|
$data = array_merge($data, self::getViewModel($invoice));
|
||||||
|
|
||||||
return View::make('invoices.edit', $data);
|
return View::make('invoices.edit', $data);
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ class InvoiceController extends BaseController
|
|||||||
return self::create($clientPublicId, true);
|
return self::create($clientPublicId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getViewModel()
|
private static function getViewModel($invoice)
|
||||||
{
|
{
|
||||||
$recurringHelp = '';
|
$recurringHelp = '';
|
||||||
foreach (preg_split("/((\r?\n)|(\r\n?))/", trans('texts.recurring_help')) as $line) {
|
foreach (preg_split("/((\r?\n)|(\r\n?))/", trans('texts.recurring_help')) as $line) {
|
||||||
@ -332,17 +332,37 @@ class InvoiceController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tax rate options
|
// Tax rate $options
|
||||||
|
$account = Auth::user()->account;
|
||||||
$rates = TaxRate::scope()->orderBy('name')->get();
|
$rates = TaxRate::scope()->orderBy('name')->get();
|
||||||
|
$options = [];
|
||||||
|
$defaultTax = false;
|
||||||
|
|
||||||
foreach ($rates as $rate) {
|
foreach ($rates as $rate) {
|
||||||
$options[$rate->rate . ' ' . $rate->name] = $rate->name . ' ' . ($rate->rate+0) . '%';
|
$options[$rate->rate . ' ' . $rate->name] = $rate->name . ' ' . ($rate->rate+0) . '%';
|
||||||
|
|
||||||
|
// load default invoice tax
|
||||||
|
if ($rate->id == $account->default_tax_rate_id) {
|
||||||
|
$defaultTax = $rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for any taxes which have been deleted
|
||||||
|
if ($invoice->exists) {
|
||||||
|
foreach ($invoice->getTaxes() as $key => $rate) {
|
||||||
|
if (isset($options[$key])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$options[$key] = $rate['name'] . ' ' . $rate['rate'] . '%';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'data' => Input::old('data'),
|
'data' => Input::old('data'),
|
||||||
'account' => Auth::user()->account->load('country'),
|
'account' => Auth::user()->account->load('country'),
|
||||||
'products' => Product::scope()->with('default_tax_rate')->orderBy('product_key')->get(),
|
'products' => Product::scope()->with('default_tax_rate')->orderBy('product_key')->get(),
|
||||||
'taxRates' => $options,
|
'taxRateOptions' => $options,
|
||||||
|
'defaultTax' => $defaultTax,
|
||||||
'currencies' => Cache::get('currencies'),
|
'currencies' => Cache::get('currencies'),
|
||||||
'languages' => Cache::get('languages'),
|
'languages' => Cache::get('languages'),
|
||||||
'sizes' => Cache::get('sizes'),
|
'sizes' => Cache::get('sizes'),
|
||||||
|
@ -853,9 +853,9 @@ class Invoice extends EntityModel implements BalanceAffecting
|
|||||||
$taxAmount = round($taxAmount, 2);
|
$taxAmount = round($taxAmount, 2);
|
||||||
|
|
||||||
if ($taxAmount) {
|
if ($taxAmount) {
|
||||||
$taxes[$this->tax_name.$this->tax_rate] = [
|
$taxes[$this->tax_rate . ' ' . $this->tax_name] = [
|
||||||
'name' => $this->tax_name,
|
'name' => $this->tax_name,
|
||||||
'rate' => $this->tax_rate,
|
'rate' => $this->tax_rate+0,
|
||||||
'amount' => $taxAmount,
|
'amount' => $taxAmount,
|
||||||
'paid' => round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2)
|
'paid' => round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2)
|
||||||
];
|
];
|
||||||
@ -872,7 +872,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
|||||||
$taxAmount = round($taxAmount, 2);
|
$taxAmount = round($taxAmount, 2);
|
||||||
|
|
||||||
if ($taxAmount) {
|
if ($taxAmount) {
|
||||||
$key = $invoiceItem->tax_name.$invoiceItem->tax_rate;
|
$key = $invoiceItem->tax_rate . ' ' . $invoiceItem->tax_name;
|
||||||
|
|
||||||
if ( ! isset($taxes[$key])) {
|
if ( ! isset($taxes[$key])) {
|
||||||
$taxes[$key] = [
|
$taxes[$key] = [
|
||||||
@ -884,7 +884,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
|||||||
$taxes[$key]['amount'] += $taxAmount;
|
$taxes[$key]['amount'] += $taxAmount;
|
||||||
$taxes[$key]['paid'] += $this->amount && $taxAmount ? round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2) : 0;
|
$taxes[$key]['paid'] += $this->amount && $taxAmount ? round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2) : 0;
|
||||||
$taxes[$key]['name'] = $invoiceItem->tax_name;
|
$taxes[$key]['name'] = $invoiceItem->tax_name;
|
||||||
$taxes[$key]['rate'] = $invoiceItem->tax_rate;
|
$taxes[$key]['rate'] = $invoiceItem->tax_rate+0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php namespace App\Models;
|
<?php namespace App\Models;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class TaxRate extends EntityModel
|
class TaxRate extends EntityModel
|
||||||
|
File diff suppressed because one or more lines are too long
@ -465,7 +465,7 @@ NINJA.subtotals = function(invoice, hideBalance)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invoice.tax && invoice.tax.name || invoice.tax_name) {
|
if (invoice.tax_amount) {
|
||||||
var taxStr = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%';
|
var taxStr = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%';
|
||||||
data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount, invoice)}]);
|
data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount, invoice)}]);
|
||||||
}
|
}
|
||||||
|
@ -612,11 +612,7 @@ function calculateAmounts(invoice) {
|
|||||||
invoice.has_product_key = true;
|
invoice.has_product_key = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the object structure differs if it's read from the db or created by knockoutJS
|
if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||||||
if (item.tax && parseFloat(item.tax.rate)) {
|
|
||||||
taxRate = parseFloat(item.tax.rate);
|
|
||||||
taxName = item.tax.name;
|
|
||||||
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
|
||||||
taxRate = parseFloat(item.tax_rate);
|
taxRate = parseFloat(item.tax_rate);
|
||||||
taxName = item.tax_name;
|
taxName = item.tax_name;
|
||||||
}
|
}
|
||||||
@ -632,7 +628,7 @@ function calculateAmounts(invoice) {
|
|||||||
}
|
}
|
||||||
var taxAmount = roundToTwo(lineTotal * taxRate / 100);
|
var taxAmount = roundToTwo(lineTotal * taxRate / 100);
|
||||||
|
|
||||||
if (taxRate) {
|
if (taxAmount) {
|
||||||
var key = taxName + taxRate;
|
var key = taxName + taxRate;
|
||||||
if (taxes.hasOwnProperty(key)) {
|
if (taxes.hasOwnProperty(key)) {
|
||||||
taxes[key].amount += taxAmount;
|
taxes[key].amount += taxAmount;
|
||||||
@ -641,7 +637,7 @@ function calculateAmounts(invoice) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((item.tax && item.tax.name) || item.tax_name) {
|
if (item.tax_name) {
|
||||||
hasTaxes = true;
|
hasTaxes = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -667,9 +663,7 @@ function calculateAmounts(invoice) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tax = 0;
|
var tax = 0;
|
||||||
if (invoice.tax && parseFloat(invoice.tax.rate)) {
|
if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||||||
tax = parseFloat(invoice.tax.rate);
|
|
||||||
} else if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
|
||||||
tax = parseFloat(invoice.tax_rate);
|
tax = parseFloat(invoice.tax_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,9 +702,7 @@ function calculateAmounts(invoice) {
|
|||||||
|
|
||||||
function getInvoiceTaxRate(invoice) {
|
function getInvoiceTaxRate(invoice) {
|
||||||
var tax = 0;
|
var tax = 0;
|
||||||
if (invoice.tax && parseFloat(invoice.tax.rate)) {
|
if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||||||
tax = parseFloat(invoice.tax.rate);
|
|
||||||
} else if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
|
||||||
tax = parseFloat(invoice.tax_rate);
|
tax = parseFloat(invoice.tax_rate);
|
||||||
}
|
}
|
||||||
return tax;
|
return tax;
|
||||||
|
@ -1102,7 +1102,7 @@ $LANG = array(
|
|||||||
'email_documents_header' => 'Documents:',
|
'email_documents_header' => 'Documents:',
|
||||||
'email_documents_example_1' => 'Widgets Receipt.pdf',
|
'email_documents_example_1' => 'Widgets Receipt.pdf',
|
||||||
'email_documents_example_2' => 'Final Deliverable.zip',
|
'email_documents_example_2' => 'Final Deliverable.zip',
|
||||||
'invoice_documents' => 'Attached Documents',
|
'invoice_documents' => 'Documents',
|
||||||
'expense_documents' => 'Attached Documents',
|
'expense_documents' => 'Attached Documents',
|
||||||
'invoice_embed_documents' => 'Embed Documents',
|
'invoice_embed_documents' => 'Embed Documents',
|
||||||
'invoice_embed_documents_help' => 'Include attached images in the invoice.',
|
'invoice_embed_documents_help' => 'Include attached images in the invoice.',
|
||||||
|
@ -244,7 +244,8 @@
|
|||||||
</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('')
|
||||||
->options($taxRates)
|
->addOption('', '')
|
||||||
|
->options($taxRateOptions)
|
||||||
->data_bind('value: tax')
|
->data_bind('value: tax')
|
||||||
->raw() !!}
|
->raw() !!}
|
||||||
<input type="text" data-bind="value: tax_name, attr: {name: 'invoice_items[' + $index() + '][tax_name]'}" style="display:none">
|
<input type="text" data-bind="value: tax_name, attr: {name: 'invoice_items[' + $index() + '][tax_name]'}" style="display:none">
|
||||||
@ -274,7 +275,7 @@
|
|||||||
<li role="presentation"><a href="#terms" aria-controls="terms" role="tab" data-toggle="tab">{{ trans("texts.{$entityType}_terms") }}</a></li>
|
<li role="presentation"><a href="#terms" aria-controls="terms" role="tab" data-toggle="tab">{{ trans("texts.{$entityType}_terms") }}</a></li>
|
||||||
<li role="presentation"><a href="#footer" aria-controls="footer" role="tab" data-toggle="tab">{{ trans("texts.{$entityType}_footer") }}</a></li>
|
<li role="presentation"><a href="#footer" aria-controls="footer" role="tab" data-toggle="tab">{{ trans("texts.{$entityType}_footer") }}</a></li>
|
||||||
@if ($account->isPro())
|
@if ($account->isPro())
|
||||||
<li role="presentation"><a href="#attached-documents" aria-controls="attached-documents" role="tab" data-toggle="tab">{{ trans("texts.invoice_documents") }}</a></li>
|
<li role="presentation"><a href="#attached-documents" aria-controls="attached-documents" role="tab" data-toggle="tab">{{ trans("texts.invoice_documents") }}</a></li>
|
||||||
@endif
|
@endif
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -384,7 +385,8 @@
|
|||||||
@endif
|
@endif
|
||||||
<td style="min-width:120px">
|
<td style="min-width:120px">
|
||||||
{!! Former::select('')
|
{!! Former::select('')
|
||||||
->options($taxRates)
|
->addOption('', '')
|
||||||
|
->options($taxRateOptions)
|
||||||
->data_bind('value: tax')
|
->data_bind('value: tax')
|
||||||
->raw() !!}
|
->raw() !!}
|
||||||
<input type="text" name="tax_name" data-bind="value: tax_name" style="display:none">
|
<input type="text" name="tax_name" data-bind="value: tax_name" style="display:none">
|
||||||
@ -722,7 +724,6 @@
|
|||||||
var invoiceDesigns = {!! $invoiceDesigns !!};
|
var invoiceDesigns = {!! $invoiceDesigns !!};
|
||||||
var invoiceFonts = {!! $invoiceFonts !!};
|
var invoiceFonts = {!! $invoiceFonts !!};
|
||||||
|
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
// create client dictionary
|
// create client dictionary
|
||||||
for (var i=0; i<clients.length; i++) {
|
for (var i=0; i<clients.length; i++) {
|
||||||
@ -767,8 +768,10 @@
|
|||||||
model.invoice().custom_taxes1({{ $account->custom_invoice_taxes1 ? 'true' : 'false' }});
|
model.invoice().custom_taxes1({{ $account->custom_invoice_taxes1 ? 'true' : 'false' }});
|
||||||
model.invoice().custom_taxes2({{ $account->custom_invoice_taxes2 ? 'true' : 'false' }});
|
model.invoice().custom_taxes2({{ $account->custom_invoice_taxes2 ? 'true' : 'false' }});
|
||||||
// set the default account tax rate
|
// set the default account tax rate
|
||||||
@if ($account->invoice_taxes && $account->default_tax_rate_id)
|
@if ($account->invoice_taxes && ! empty($defaultTax))
|
||||||
//model.invoice().tax(model.getTaxRateById({{ $account->default_tax_rate ? $account->default_tax_rate->public_id : '' }}));
|
var defaultTax = {!! $defaultTax !!};
|
||||||
|
model.invoice().tax_rate(defaultTax.rate);
|
||||||
|
model.invoice().tax_name(defaultTax.name);
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@ -794,7 +794,9 @@ ko.bindingHandlers.typeahead = {
|
|||||||
}
|
}
|
||||||
@if ($account->invoice_item_taxes)
|
@if ($account->invoice_item_taxes)
|
||||||
if (datum.default_tax_rate) {
|
if (datum.default_tax_rate) {
|
||||||
//model.tax(self.model.getTaxRateById(datum.default_tax_rate.public_id));
|
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);
|
||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user