mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-17 16:42:48 +01:00
Support for multiple tax rates
This commit is contained in:
parent
f91f32323f
commit
be9e7beaed
@ -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);
|
||||
|
@ -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,52 +854,66 @@ 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();
|
||||
$paidAmount = $this->getAmountPaid($calculatePaid);
|
||||
|
||||
if ($this->tax_rate && $this->tax_name) {
|
||||
$taxAmount = $taxable * ($this->tax_rate / 100);
|
||||
$taxAmount = round($taxAmount, 2);
|
||||
|
||||
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_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 ($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 ($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);
|
||||
}
|
||||
}
|
||||
|
||||
if ($taxAmount) {
|
||||
$key = $invoiceItem->tax_rate . ' ' . $invoiceItem->tax_name;
|
||||
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'] += $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;
|
||||
}
|
||||
}
|
||||
|
||||
return $taxes;
|
||||
$taxes[$key]['amount'] += $amount;
|
||||
$taxes[$key]['paid'] += $paid;
|
||||
}
|
||||
|
||||
public function hasDocuments(){
|
||||
|
@ -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');
|
||||
|
@ -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,10 +323,8 @@ 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;
|
||||
|
||||
if ($invoice->discount > 0) {
|
||||
@ -337,6 +335,12 @@ class InvoiceRepository extends BaseRepository
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
];
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
@ -19,6 +19,20 @@ class SupportMultipleTaxRates extends Migration
|
||||
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);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
@ -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');
|
||||
});
|
||||
}
|
||||
}
|
@ -30497,8 +30497,10 @@ function calculateAmounts(invoice) {
|
||||
|
||||
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||||
var item = invoice.invoice_items[i];
|
||||
var taxRate = 0;
|
||||
var taxName = '';
|
||||
var taxRate1 = 0;
|
||||
var taxName1 = '';
|
||||
var taxRate2 = 0;
|
||||
var taxName2 = '';
|
||||
|
||||
if (item.product_key) {
|
||||
invoice.has_product_key = true;
|
||||
@ -30506,9 +30508,14 @@ function calculateAmounts(invoice) {
|
||||
invoice.has_product_key = true;
|
||||
}
|
||||
|
||||
if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||||
taxRate = parseFloat(item.tax_rate);
|
||||
taxName = item.tax_name;
|
||||
if (item.tax_rate1 && parseFloat(item.tax_rate1)) {
|
||||
taxRate1 = parseFloat(item.tax_rate1);
|
||||
taxName1 = item.tax_name1;
|
||||
}
|
||||
|
||||
if (item.tax_rate2 && parseFloat(item.tax_rate2)) {
|
||||
taxRate2 = parseFloat(item.tax_rate2);
|
||||
taxName2 = item.tax_name2;
|
||||
}
|
||||
|
||||
// calculate line item tax
|
||||
@ -30520,18 +30527,28 @@ function calculateAmounts(invoice) {
|
||||
lineTotal -= roundToTwo(lineTotal * (invoice.discount/100));
|
||||
}
|
||||
}
|
||||
var taxAmount = roundToTwo(lineTotal * taxRate / 100);
|
||||
|
||||
if (taxAmount) {
|
||||
var key = taxName + taxRate;
|
||||
var taxAmount1 = roundToTwo(lineTotal * taxRate1 / 100);
|
||||
if (taxAmount1) {
|
||||
var key = taxName1 + taxRate1;
|
||||
if (taxes.hasOwnProperty(key)) {
|
||||
taxes[key].amount += taxAmount;
|
||||
taxes[key].amount += taxAmount1;
|
||||
} else {
|
||||
taxes[key] = {name: taxName, rate:taxRate, amount:taxAmount};
|
||||
taxes[key] = {name: taxName1, rate:taxRate1, amount:taxAmount1};
|
||||
}
|
||||
}
|
||||
|
||||
if (item.tax_name) {
|
||||
var taxAmount2 = roundToTwo(lineTotal * taxRate2 / 100);
|
||||
if (taxAmount2) {
|
||||
var key = taxName2 + taxRate2;
|
||||
if (taxes.hasOwnProperty(key)) {
|
||||
taxes[key].amount += taxAmount2;
|
||||
} else {
|
||||
taxes[key] = {name: taxName2, rate:taxRate2, amount:taxAmount2};
|
||||
}
|
||||
}
|
||||
|
||||
if (item.tax_name1 || item.tax_name2) {
|
||||
hasTaxes = true;
|
||||
}
|
||||
}
|
||||
@ -30556,15 +30573,17 @@ function calculateAmounts(invoice) {
|
||||
total += roundToTwo(invoice.custom_value2);
|
||||
}
|
||||
|
||||
var tax = 0;
|
||||
if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||||
tax = parseFloat(invoice.tax_rate);
|
||||
taxRate1 = 0;
|
||||
taxRate2 = 0;
|
||||
if (invoice.tax_rate1 && parseFloat(invoice.tax_rate1)) {
|
||||
taxRate1 = parseFloat(invoice.tax_rate1);
|
||||
}
|
||||
|
||||
if (tax) {
|
||||
var tax = roundToTwo(total * (tax/100));
|
||||
total = parseFloat(total) + parseFloat(tax);
|
||||
if (invoice.tax_rate2 && parseFloat(invoice.tax_rate2)) {
|
||||
taxRate2 = parseFloat(invoice.tax_rate2);
|
||||
}
|
||||
taxAmount1 = roundToTwo(total * (taxRate1/100));
|
||||
taxAmount2 = roundToTwo(total * (taxRate2/100));
|
||||
total = total + taxAmount1 + taxAmount2;
|
||||
|
||||
for (var key in taxes) {
|
||||
if (taxes.hasOwnProperty(key)) {
|
||||
@ -30582,7 +30601,8 @@ function calculateAmounts(invoice) {
|
||||
|
||||
invoice.total_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
|
||||
invoice.discount_amount = discount;
|
||||
invoice.tax_amount = tax;
|
||||
invoice.tax_amount1 = taxAmount1;
|
||||
invoice.tax_amount2 = taxAmount2;
|
||||
invoice.item_taxes = taxes;
|
||||
|
||||
if (NINJA.parseFloat(invoice.partial)) {
|
||||
@ -30594,14 +30614,6 @@ function calculateAmounts(invoice) {
|
||||
return invoice;
|
||||
}
|
||||
|
||||
function getInvoiceTaxRate(invoice) {
|
||||
var tax = 0;
|
||||
if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||||
tax = parseFloat(invoice.tax_rate);
|
||||
}
|
||||
return tax;
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/11941876/correctly-suppressing-warnings-in-datatables
|
||||
window.alert = (function() {
|
||||
var nativeAlert = window.alert;
|
||||
@ -31337,13 +31349,15 @@ NINJA.invoiceLines = function(invoice) {
|
||||
var qty = NINJA.parseFloat(item.qty) ? roundToTwo(NINJA.parseFloat(item.qty)) + '' : '';
|
||||
var notes = item.notes;
|
||||
var productKey = item.product_key;
|
||||
var tax = '';
|
||||
var tax1 = '';
|
||||
var tax2 = '';
|
||||
|
||||
if (showItemTaxes) {
|
||||
if (item.tax && parseFloat(item.tax.rate)) {
|
||||
tax = parseFloat(item.tax.rate);
|
||||
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||||
tax = parseFloat(item.tax_rate);
|
||||
if (item.tax_name1) {
|
||||
tax1 = parseFloat(item.tax_rate1);
|
||||
}
|
||||
if (item.tax_name2) {
|
||||
tax2 = parseFloat(item.tax_rate2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -31380,7 +31394,14 @@ NINJA.invoiceLines = function(invoice) {
|
||||
row.push({style:["quantity", rowStyle], text:qty || ' '});
|
||||
}
|
||||
if (showItemTaxes) {
|
||||
row.push({style:["tax", rowStyle], text:tax ? (tax.toString() + '%') : ' '});
|
||||
var str = '';
|
||||
if (tax1) {
|
||||
str += tax1.toString() + '% ';
|
||||
}
|
||||
if (tax2) {
|
||||
str += tax2.toString() + '% ';
|
||||
}
|
||||
row.push({style:["tax", rowStyle], text:str});
|
||||
}
|
||||
row.push({style:["lineTotal", rowStyle], text:lineTotal || ' '});
|
||||
|
||||
@ -31452,9 +31473,13 @@ NINJA.subtotals = function(invoice, hideBalance)
|
||||
}
|
||||
}
|
||||
|
||||
if (invoice.tax_amount) {
|
||||
var taxStr = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%';
|
||||
data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount, invoice)}]);
|
||||
if (invoice.tax_amount1) {
|
||||
var taxStr = invoice.tax_name1 + ' ' + (invoice.tax_rate1*1).toString() + '%';
|
||||
data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount1, invoice)}]);
|
||||
}
|
||||
if (invoice.tax_amount2) {
|
||||
var taxStr = invoice.tax_name2 + ' ' + (invoice.tax_rate2*1).toString() + '%';
|
||||
data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount2, invoice)}]);
|
||||
}
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
|
@ -350,13 +350,15 @@ NINJA.invoiceLines = function(invoice) {
|
||||
var qty = NINJA.parseFloat(item.qty) ? roundToTwo(NINJA.parseFloat(item.qty)) + '' : '';
|
||||
var notes = item.notes;
|
||||
var productKey = item.product_key;
|
||||
var tax = '';
|
||||
var tax1 = '';
|
||||
var tax2 = '';
|
||||
|
||||
if (showItemTaxes) {
|
||||
if (item.tax && parseFloat(item.tax.rate)) {
|
||||
tax = parseFloat(item.tax.rate);
|
||||
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||||
tax = parseFloat(item.tax_rate);
|
||||
if (item.tax_name1) {
|
||||
tax1 = parseFloat(item.tax_rate1);
|
||||
}
|
||||
if (item.tax_name2) {
|
||||
tax2 = parseFloat(item.tax_rate2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,7 +395,14 @@ NINJA.invoiceLines = function(invoice) {
|
||||
row.push({style:["quantity", rowStyle], text:qty || ' '});
|
||||
}
|
||||
if (showItemTaxes) {
|
||||
row.push({style:["tax", rowStyle], text:tax ? (tax.toString() + '%') : ' '});
|
||||
var str = '';
|
||||
if (tax1) {
|
||||
str += tax1.toString() + '% ';
|
||||
}
|
||||
if (tax2) {
|
||||
str += tax2.toString() + '% ';
|
||||
}
|
||||
row.push({style:["tax", rowStyle], text:str});
|
||||
}
|
||||
row.push({style:["lineTotal", rowStyle], text:lineTotal || ' '});
|
||||
|
||||
@ -465,9 +474,13 @@ NINJA.subtotals = function(invoice, hideBalance)
|
||||
}
|
||||
}
|
||||
|
||||
if (invoice.tax_amount) {
|
||||
var taxStr = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%';
|
||||
data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount, invoice)}]);
|
||||
if (invoice.tax_amount1) {
|
||||
var taxStr = invoice.tax_name1 + ' ' + (invoice.tax_rate1*1).toString() + '%';
|
||||
data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount1, invoice)}]);
|
||||
}
|
||||
if (invoice.tax_amount2) {
|
||||
var taxStr = invoice.tax_name2 + ' ' + (invoice.tax_rate2*1).toString() + '%';
|
||||
data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount2, invoice)}]);
|
||||
}
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
|
@ -603,8 +603,10 @@ function calculateAmounts(invoice) {
|
||||
|
||||
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||||
var item = invoice.invoice_items[i];
|
||||
var taxRate = 0;
|
||||
var taxName = '';
|
||||
var taxRate1 = 0;
|
||||
var taxName1 = '';
|
||||
var taxRate2 = 0;
|
||||
var taxName2 = '';
|
||||
|
||||
if (item.product_key) {
|
||||
invoice.has_product_key = true;
|
||||
@ -612,9 +614,14 @@ function calculateAmounts(invoice) {
|
||||
invoice.has_product_key = true;
|
||||
}
|
||||
|
||||
if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||||
taxRate = parseFloat(item.tax_rate);
|
||||
taxName = item.tax_name;
|
||||
if (item.tax_rate1 && parseFloat(item.tax_rate1)) {
|
||||
taxRate1 = parseFloat(item.tax_rate1);
|
||||
taxName1 = item.tax_name1;
|
||||
}
|
||||
|
||||
if (item.tax_rate2 && parseFloat(item.tax_rate2)) {
|
||||
taxRate2 = parseFloat(item.tax_rate2);
|
||||
taxName2 = item.tax_name2;
|
||||
}
|
||||
|
||||
// calculate line item tax
|
||||
@ -626,18 +633,28 @@ function calculateAmounts(invoice) {
|
||||
lineTotal -= roundToTwo(lineTotal * (invoice.discount/100));
|
||||
}
|
||||
}
|
||||
var taxAmount = roundToTwo(lineTotal * taxRate / 100);
|
||||
|
||||
if (taxAmount) {
|
||||
var key = taxName + taxRate;
|
||||
var taxAmount1 = roundToTwo(lineTotal * taxRate1 / 100);
|
||||
if (taxAmount1) {
|
||||
var key = taxName1 + taxRate1;
|
||||
if (taxes.hasOwnProperty(key)) {
|
||||
taxes[key].amount += taxAmount;
|
||||
taxes[key].amount += taxAmount1;
|
||||
} else {
|
||||
taxes[key] = {name: taxName, rate:taxRate, amount:taxAmount};
|
||||
taxes[key] = {name: taxName1, rate:taxRate1, amount:taxAmount1};
|
||||
}
|
||||
}
|
||||
|
||||
if (item.tax_name) {
|
||||
var taxAmount2 = roundToTwo(lineTotal * taxRate2 / 100);
|
||||
if (taxAmount2) {
|
||||
var key = taxName2 + taxRate2;
|
||||
if (taxes.hasOwnProperty(key)) {
|
||||
taxes[key].amount += taxAmount2;
|
||||
} else {
|
||||
taxes[key] = {name: taxName2, rate:taxRate2, amount:taxAmount2};
|
||||
}
|
||||
}
|
||||
|
||||
if (item.tax_name1 || item.tax_name2) {
|
||||
hasTaxes = true;
|
||||
}
|
||||
}
|
||||
@ -662,15 +679,17 @@ function calculateAmounts(invoice) {
|
||||
total += roundToTwo(invoice.custom_value2);
|
||||
}
|
||||
|
||||
var tax = 0;
|
||||
if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||||
tax = parseFloat(invoice.tax_rate);
|
||||
taxRate1 = 0;
|
||||
taxRate2 = 0;
|
||||
if (invoice.tax_rate1 && parseFloat(invoice.tax_rate1)) {
|
||||
taxRate1 = parseFloat(invoice.tax_rate1);
|
||||
}
|
||||
|
||||
if (tax) {
|
||||
var tax = roundToTwo(total * (tax/100));
|
||||
total = parseFloat(total) + parseFloat(tax);
|
||||
if (invoice.tax_rate2 && parseFloat(invoice.tax_rate2)) {
|
||||
taxRate2 = parseFloat(invoice.tax_rate2);
|
||||
}
|
||||
taxAmount1 = roundToTwo(total * (taxRate1/100));
|
||||
taxAmount2 = roundToTwo(total * (taxRate2/100));
|
||||
total = total + taxAmount1 + taxAmount2;
|
||||
|
||||
for (var key in taxes) {
|
||||
if (taxes.hasOwnProperty(key)) {
|
||||
@ -688,7 +707,8 @@ function calculateAmounts(invoice) {
|
||||
|
||||
invoice.total_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
|
||||
invoice.discount_amount = discount;
|
||||
invoice.tax_amount = tax;
|
||||
invoice.tax_amount1 = taxAmount1;
|
||||
invoice.tax_amount2 = taxAmount2;
|
||||
invoice.item_taxes = taxes;
|
||||
|
||||
if (NINJA.parseFloat(invoice.partial)) {
|
||||
@ -700,14 +720,6 @@ function calculateAmounts(invoice) {
|
||||
return invoice;
|
||||
}
|
||||
|
||||
function getInvoiceTaxRate(invoice) {
|
||||
var tax = 0;
|
||||
if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||||
tax = parseFloat(invoice.tax_rate);
|
||||
}
|
||||
return tax;
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/11941876/correctly-suppressing-warnings-in-datatables
|
||||
window.alert = (function() {
|
||||
var nativeAlert = window.alert;
|
||||
|
@ -17,6 +17,11 @@
|
||||
label.control-label[for=invoice_number] {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
select.tax-select {
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
</style>
|
||||
@stop
|
||||
|
||||
@ -204,7 +209,7 @@
|
||||
@endif
|
||||
<th style="min-width:120px" data-bind="text: costLabel">{{ $invoiceLabels['unit_cost'] }}</th>
|
||||
<th style="{{ $account->hide_quantity ? 'display:none' : 'min-width:120px' }}" data-bind="text: qtyLabel">{{ $invoiceLabels['quantity'] }}</th>
|
||||
<th style="min-width:120px;display:none;" data-bind="visible: $root.invoice_item_taxes.show">{{ trans('texts.tax') }}</th>
|
||||
<th style="min-width:180px;display:none;" data-bind="visible: $root.invoice_item_taxes.show">{{ trans('texts.tax') }}</th>
|
||||
<th style="min-width:120px;">{{ trans('texts.line_total') }}</th>
|
||||
<th style="min-width:32px;" class="hide-border"></th>
|
||||
</tr>
|
||||
@ -246,10 +251,19 @@
|
||||
{!! Former::select('')
|
||||
->addOption('', '')
|
||||
->options($taxRateOptions)
|
||||
->data_bind('value: tax')
|
||||
->data_bind('value: tax1')
|
||||
->addClass('tax-select')
|
||||
->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_rate, attr: {name: 'invoice_items[' + $index() + '][tax_rate]'}" 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">
|
||||
{!! Former::select('')
|
||||
->addOption('', '')
|
||||
->options($taxRateOptions)
|
||||
->data_bind('value: tax2')
|
||||
->addClass('tax-select')
|
||||
->raw() !!}
|
||||
<input type="text" data-bind="value: tax_name2, attr: {name: 'invoice_items[' + $index() + '][tax_name2]'}" style="display:none">
|
||||
<input type="text" data-bind="value: tax_rate2, attr: {name: 'invoice_items[' + $index() + '][tax_rate2]'}" style="display:none">
|
||||
</td>
|
||||
<td style="text-align:right;padding-top:9px !important" nowrap>
|
||||
<div class="line-total" data-bind="text: totals.total"></div>
|
||||
@ -387,10 +401,19 @@
|
||||
{!! Former::select('')
|
||||
->addOption('', '')
|
||||
->options($taxRateOptions)
|
||||
->data_bind('value: tax')
|
||||
->addClass('tax-select')
|
||||
->data_bind('value: tax1')
|
||||
->raw() !!}
|
||||
<input type="text" name="tax_name" data-bind="value: tax_name" style="display:none">
|
||||
<input type="text" name="tax_rate" data-bind="value: tax_rate" 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">
|
||||
{!! Former::select('')
|
||||
->addOption('', '')
|
||||
->options($taxRateOptions)
|
||||
->addClass('tax-select')
|
||||
->data_bind('value: tax2')
|
||||
->raw() !!}
|
||||
<input type="text" name="tax_name2" data-bind="value: tax_name2" style="display:none">
|
||||
<input type="text" name="tax_rate2" data-bind="value: tax_rate2" style="display:none">
|
||||
</td>
|
||||
<td style="text-align: right"><span data-bind="text: totals.taxAmount"/></td>
|
||||
</tr>
|
||||
@ -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
|
||||
|
||||
|
@ -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<self.invoice().invoice_items().length; i++) {
|
||||
var item = self.invoice().invoice_items()[i];
|
||||
if (item.tax_rate() > 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
|
||||
|
Loading…
Reference in New Issue
Block a user