Moved line item tax amounts to invoice subtotals section

This commit is contained in:
Hillel Coren 2015-08-12 22:16:02 +03:00
parent 8afd68fe23
commit dc8bd36e76
29 changed files with 278 additions and 186 deletions

View File

@ -110,7 +110,8 @@ class AccountController extends BaseController
Auth::login($user, true);
Event::fire(new UserLoggedIn());
return Redirect::to('invoices/create')->with('sign_up', Input::get('sign_up'));
$redirectTo = Input::get('redirect_to', 'invoices/create');
return Redirect::to($redirectTo)->with('sign_up', Input::get('sign_up'));
}
public function enableProPlan()
@ -235,7 +236,7 @@ class AccountController extends BaseController
$data['invoice'] = $invoice;
$data['invoiceLabels'] = json_decode($account->invoice_labels) ?: [];
$data['title'] = trans('texts.invoice_design');
$data['invoiceDesigns'] = InvoiceDesign::getDesigns($subSection == ACCOUNT_CUSTOMIZE_DESIGN);
$data['invoiceDesigns'] = InvoiceDesign::getDesigns();
$design = false;
foreach ($data['invoiceDesigns'] as $item) {
@ -301,11 +302,6 @@ class AccountController extends BaseController
$account = Auth::user()->account;
$account->custom_design = Input::get('custom_design');
$account->invoice_design_id = CUSTOM_DESIGN;
if (!$account->utf8_invoices) {
$account->utf8_invoices = true;
}
$account->save();
Session::flash('message', trans('texts.updated_settings'));
@ -365,7 +361,6 @@ class AccountController extends BaseController
$account->share_counter = Input::get('share_counter') ? true : false;
$account->pdf_email_attachment = Input::get('pdf_email_attachment') ? true : false;
$account->utf8_invoices = Input::get('utf8_invoices') ? true : false;
$account->auto_wrap = Input::get('auto_wrap') ? true : false;
if (!$account->share_counter) {
@ -706,9 +701,9 @@ class AccountController extends BaseController
$image = Image::make($path);
$mimeType = $file->getMimeType();
if ($mimeType == 'image/jpeg' && $account->utf8_invoices) {
if ($mimeType == 'image/jpeg') {
$file->move('logo/', $account->account_key . '.jpg');
} else if ($mimeType == 'image/png' && $account->utf8_invoices) {
} else if ($mimeType == 'image/png') {
$file->move('logo/', $account->account_key . '.png');
} else {
$image->resize(200, 120, function ($constraint) {

View File

@ -50,7 +50,8 @@ class HomeController extends BaseController
}
if (Auth::check()) {
return Redirect::to('invoices/create')->with('sign_up', Input::get('sign_up'));
$redirectTo = Input::get('redirect_to', 'invoices/create');
return Redirect::to($redirectTo)->with('sign_up', Input::get('sign_up'));
} else {
return View::make('public.header', ['invoiceNow' => true]);
}

View File

@ -214,7 +214,7 @@ class InvoiceController extends BaseController
if ($invoice->invoice_design_id == CUSTOM_DESIGN) {
$invoice->invoice_design->javascript = $account->custom_design;
} elseif ($account->utf8_invoices) {
} else {
$invoice->invoice_design->javascript = $invoice->invoice_design->pdfmake;
}

View File

@ -12,9 +12,11 @@ class Account extends Eloquent
use SoftDeletes;
protected $dates = ['deleted_at'];
/*
protected $casts = [
'utf8_invoice' => 'boolean',
'hide_quantity' => 'boolean',
];
*/
public function users()
{
@ -153,7 +155,7 @@ class Account extends Eloquent
{
$fileName = 'logo/' . $this->account_key;
return file_exists($fileName.'.png') && $this->utf8_invoices ? $fileName.'.png' : $fileName.'.jpg';
return file_exists($fileName.'.png') ? $fileName.'.png' : $fileName.'.jpg';
}
public function getLogoWidth()
@ -428,10 +430,3 @@ class Account extends Eloquent
return $this->token_billing_type_id == TOKEN_BILLING_OPT_OUT;
}
}
Account::updating(function ($account) {
// Lithuanian requires UTF8 support
if (!Utils::isPro() && $account->language_id == 13) {
$account->utf8_invoices = true;
}
});

View File

@ -9,24 +9,21 @@ class InvoiceDesign extends Eloquent
{
public $timestamps = false;
public static function getDesigns($forceUtf8 = false)
public static function getDesigns()
{
$account = Auth::user()->account;
$designs = Cache::get('invoiceDesigns');
$utf8 = $forceUtf8 || $account->utf8_invoices;
foreach ($designs as $design) {
if ($design->id > Auth::user()->maxInvoiceDesignId()) {
$designs->pull($design->id);
}
if ($utf8) {
$design->javascript = $design->pdfmake;
}
$design->pdfmake = null;
if ($design->id == CUSTOM_DESIGN) {
if ($utf8 && $account->custom_design) {
if ($account->custom_design) {
$design->javascript = $account->custom_design;
} else {
$designs->pop();

View File

@ -315,6 +315,7 @@ class InvoiceRepository
}
$total = 0;
$itemTax = 0;
foreach ($data['invoice_items'] as $item) {
$item = (array) $item;
@ -324,15 +325,29 @@ class InvoiceRepository
$invoiceItemCost = round(Utils::parseFloat($item['cost']), 2);
$invoiceItemQty = round(Utils::parseFloat($item['qty']), 2);
$invoiceItemTaxRate = 0;
if (isset($item['tax_rate']) && Utils::parseFloat($item['tax_rate']) > 0) {
$invoiceItemTaxRate = Utils::parseFloat($item['tax_rate']);
}
$lineTotal = $invoiceItemCost * $invoiceItemQty;
$total += round($lineTotal, 2);
}
$total += round($lineTotal + ($lineTotal * $invoiceItemTaxRate / 100), 2);
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) {
if ($invoice->is_amount_discount) {
$lineTotal -= round(($lineTotal/$total) * $invoice->discount, 2);
} else {
$lineTotal -= round($lineTotal * ($invoice->discount/100), 2);
}
}
$itemTax += round($lineTotal * $invoiceItemTaxRate / 100, 2);
}
}
if ($invoice->discount > 0) {
@ -358,6 +373,7 @@ class InvoiceRepository
$total += $total * $invoice->tax_rate / 100;
$total = round($total, 2);
$total += $itemTax;
// custom fields not charged taxes
if ($invoice->custom_value1 && !$invoice->custom_taxes1) {

View File

@ -30799,22 +30799,49 @@ function displayNotesAndTerms(doc, layout, invoice, y)
function calculateAmounts(invoice) {
var total = 0;
var hasTaxes = false;
var taxes = {};
// sum line item
for (var i=0; i<invoice.invoice_items.length; i++) {
var item = invoice.invoice_items[i];
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (lineTotal) {
total += lineTotal;
}
}
for (var i=0; i<invoice.invoice_items.length; i++) {
var item = invoice.invoice_items[i];
var tax = 0;
var taxRate = 0;
var taxName = '';
// the object structure differs if it's read from the db or created by knockoutJS
if (item.tax && parseFloat(item.tax.rate)) {
tax = parseFloat(item.tax.rate);
taxRate = parseFloat(item.tax.rate);
taxName = item.tax.name;
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
tax = parseFloat(item.tax_rate);
taxRate = parseFloat(item.tax_rate);
taxName = item.tax_name;
}
// calculate line item tax
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += roundToTwo(lineTotal * tax / 100);
if (invoice.discount != 0) {
if (parseInt(invoice.is_amount_discount)) {
lineTotal -= roundToTwo((lineTotal/total) * invoice.discount);
} else {
lineTotal -= roundToTwo(lineTotal * (invoice.discount/100));
}
}
var taxAmount = roundToTwo(lineTotal * taxRate / 100);
if (taxRate) {
var key = taxName + taxRate;
if (taxes.hasOwnProperty(key)) {
taxes[key].amount += taxAmount;
} else {
taxes[key] = {name: taxName, rate:taxRate, amount:taxAmount};
}
if (lineTotal) {
total += lineTotal;
}
if ((item.tax && item.tax.name) || item.tax_name) {
@ -30854,6 +30881,12 @@ function calculateAmounts(invoice) {
total = parseFloat(total) + parseFloat(tax);
}
for (var key in taxes) {
if (taxes.hasOwnProperty(key)) {
total += taxes[key].amount;
}
}
// custom fields w/o with taxes
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
total += roundToTwo(invoice.custom_value1);
@ -30865,6 +30898,7 @@ function calculateAmounts(invoice) {
invoice.total_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
invoice.discount_amount = discount;
invoice.tax_amount = tax;
invoice.item_taxes = taxes;
invoice.has_taxes = hasTaxes;
if (NINJA.parseFloat(invoice.partial)) {
@ -31655,30 +31689,31 @@ NINJA.notesAndTerms = function(invoice)
NINJA.invoiceColumns = function(invoice)
{
if (invoice.has_taxes) {
return ["15%", "*", "auto", "auto", "auto", "15%"];
if (invoice.account.hide_quantity == '1') {
return ["15%", "*", "auto", "15%"];
} else {
return ["15%", "*", "auto", "auto", "15%"]
return ["15%", "*", "auto", "auto", "15%"];
}
}
NINJA.invoiceLines = function(invoice) {
var grid = [
[
{text: invoiceLabels.item, style: ['tableHeader', 'itemTableHeader']},
{text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']},
{text: invoiceLabels.unit_cost, style: ['tableHeader', 'costTableHeader']},
{text: invoiceLabels.quantity, style: ['tableHeader', 'qtyTableHeader']},
{text: invoice.has_taxes ? invoiceLabels.tax : '', style: ['tableHeader', 'taxTableHeader']},
{text: invoiceLabels.line_total, style: ['tableHeader', 'lineTotalTableHeader']}
]
];
var total = 0;
var shownItem = false;
var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
var hideQuantity = invoice.account.hide_quantity == '1';
var grid = [[
{text: invoiceLabels.item, style: ['tableHeader', 'itemTableHeader']},
{text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']},
{text: invoiceLabels.unit_cost, style: ['tableHeader', 'costTableHeader']}
]];
if (!hideQuantity) {
grid[0].push({text: invoiceLabels.quantity, style: ['tableHeader', 'qtyTableHeader']});
}
grid[0].push({text: invoiceLabels.line_total, style: ['tableHeader', 'lineTotalTableHeader']});
for (var i = 0; i < invoice.invoice_items.length; i++) {
var row = [];
@ -31687,13 +31722,6 @@ 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 = '';
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);
}
// show at most one blank line
if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
@ -31709,12 +31737,6 @@ NINJA.invoiceLines = function(invoice) {
}
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += lineTotal * tax / 100;
}
if (lineTotal) {
total += lineTotal;
}
lineTotal = formatMoney(lineTotal, currencyId);
rowStyle = (i % 2 == 0) ? 'odd' : 'even';
@ -31722,12 +31744,9 @@ NINJA.invoiceLines = function(invoice) {
row.push({style:["productKey", rowStyle], text:productKey || ' '}); // product key can be blank when selecting from a datalist
row.push({style:["notes", rowStyle], text:notes || ' '});
row.push({style:["cost", rowStyle], text:cost});
if (!hideQuantity) {
row.push({style:["quantity", rowStyle], text:qty || ' '});
if (invoice.has_taxes) {
row.push({style:["tax", rowStyle], text: tax+'' || ''});
}
row.push({style:["lineTotal", rowStyle], text:lineTotal || ' '});
grid.push(row);
@ -31757,6 +31776,14 @@ NINJA.subtotals = function(invoice, hideBalance)
data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]);
}
for (var key in invoice.item_taxes) {
if (invoice.item_taxes.hasOwnProperty(key)) {
var taxRate = invoice.item_taxes[key];
var taxStr = taxRate.name + ' ' + (taxRate.rate*1).toString() + '%';
data.push([{text: taxStr}, {text: formatMoney(taxRate.amount, invoice.client.currency_id)}]);
}
}
if (invoice.tax && invoice.tax.name || invoice.tax_name) {
var taxStr = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%';
data.push([{text: taxStr}, {text: formatMoney(invoice.tax_amount, invoice.client.currency_id)}]);

View File

@ -181,30 +181,31 @@ NINJA.notesAndTerms = function(invoice)
NINJA.invoiceColumns = function(invoice)
{
if (invoice.has_taxes) {
return ["15%", "*", "auto", "auto", "auto", "15%"];
if (invoice.account.hide_quantity == '1') {
return ["15%", "*", "auto", "15%"];
} else {
return ["15%", "*", "auto", "auto", "15%"]
return ["15%", "*", "auto", "auto", "15%"];
}
}
NINJA.invoiceLines = function(invoice) {
var grid = [
[
{text: invoiceLabels.item, style: ['tableHeader', 'itemTableHeader']},
{text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']},
{text: invoiceLabels.unit_cost, style: ['tableHeader', 'costTableHeader']},
{text: invoiceLabels.quantity, style: ['tableHeader', 'qtyTableHeader']},
{text: invoice.has_taxes ? invoiceLabels.tax : '', style: ['tableHeader', 'taxTableHeader']},
{text: invoiceLabels.line_total, style: ['tableHeader', 'lineTotalTableHeader']}
]
];
var total = 0;
var shownItem = false;
var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
var hideQuantity = invoice.account.hide_quantity == '1';
var grid = [[
{text: invoiceLabels.item, style: ['tableHeader', 'itemTableHeader']},
{text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']},
{text: invoiceLabels.unit_cost, style: ['tableHeader', 'costTableHeader']}
]];
if (!hideQuantity) {
grid[0].push({text: invoiceLabels.quantity, style: ['tableHeader', 'qtyTableHeader']});
}
grid[0].push({text: invoiceLabels.line_total, style: ['tableHeader', 'lineTotalTableHeader']});
for (var i = 0; i < invoice.invoice_items.length; i++) {
var row = [];
@ -213,13 +214,6 @@ 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 = '';
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);
}
// show at most one blank line
if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
@ -235,12 +229,6 @@ NINJA.invoiceLines = function(invoice) {
}
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += lineTotal * tax / 100;
}
if (lineTotal) {
total += lineTotal;
}
lineTotal = formatMoney(lineTotal, currencyId);
rowStyle = (i % 2 == 0) ? 'odd' : 'even';
@ -248,12 +236,9 @@ NINJA.invoiceLines = function(invoice) {
row.push({style:["productKey", rowStyle], text:productKey || ' '}); // product key can be blank when selecting from a datalist
row.push({style:["notes", rowStyle], text:notes || ' '});
row.push({style:["cost", rowStyle], text:cost});
if (!hideQuantity) {
row.push({style:["quantity", rowStyle], text:qty || ' '});
if (invoice.has_taxes) {
row.push({style:["tax", rowStyle], text: tax+'' || ''});
}
row.push({style:["lineTotal", rowStyle], text:lineTotal || ' '});
grid.push(row);
@ -283,6 +268,14 @@ NINJA.subtotals = function(invoice, hideBalance)
data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]);
}
for (var key in invoice.item_taxes) {
if (invoice.item_taxes.hasOwnProperty(key)) {
var taxRate = invoice.item_taxes[key];
var taxStr = taxRate.name + ' ' + (taxRate.rate*1).toString() + '%';
data.push([{text: taxStr}, {text: formatMoney(taxRate.amount, invoice.client.currency_id)}]);
}
}
if (invoice.tax && invoice.tax.name || invoice.tax_name) {
var taxStr = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%';
data.push([{text: taxStr}, {text: formatMoney(invoice.tax_amount, invoice.client.currency_id)}]);

View File

@ -76,12 +76,14 @@ function GetPdf(invoice, javascript){
lineTotalRight: 550
};
/*
if (invoice.has_taxes)
{
layout.descriptionLeft -= 20;
layout.unitCostRight -= 40;
layout.qtyRight -= 40;
}
*/
/*
@param orientation One of "portrait" or "landscape" (or shortcuts "p" (Default), "l")
@ -928,22 +930,49 @@ function displayNotesAndTerms(doc, layout, invoice, y)
function calculateAmounts(invoice) {
var total = 0;
var hasTaxes = false;
var taxes = {};
// sum line item
for (var i=0; i<invoice.invoice_items.length; i++) {
var item = invoice.invoice_items[i];
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (lineTotal) {
total += lineTotal;
}
}
for (var i=0; i<invoice.invoice_items.length; i++) {
var item = invoice.invoice_items[i];
var tax = 0;
var taxRate = 0;
var taxName = '';
// the object structure differs if it's read from the db or created by knockoutJS
if (item.tax && parseFloat(item.tax.rate)) {
tax = parseFloat(item.tax.rate);
taxRate = parseFloat(item.tax.rate);
taxName = item.tax.name;
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
tax = parseFloat(item.tax_rate);
taxRate = parseFloat(item.tax_rate);
taxName = item.tax_name;
}
// calculate line item tax
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += roundToTwo(lineTotal * tax / 100);
if (invoice.discount != 0) {
if (parseInt(invoice.is_amount_discount)) {
lineTotal -= roundToTwo((lineTotal/total) * invoice.discount);
} else {
lineTotal -= roundToTwo(lineTotal * (invoice.discount/100));
}
}
var taxAmount = roundToTwo(lineTotal * taxRate / 100);
if (taxRate) {
var key = taxName + taxRate;
if (taxes.hasOwnProperty(key)) {
taxes[key].amount += taxAmount;
} else {
taxes[key] = {name: taxName, rate:taxRate, amount:taxAmount};
}
if (lineTotal) {
total += lineTotal;
}
if ((item.tax && item.tax.name) || item.tax_name) {
@ -983,6 +1012,12 @@ function calculateAmounts(invoice) {
total = parseFloat(total) + parseFloat(tax);
}
for (var key in taxes) {
if (taxes.hasOwnProperty(key)) {
total += taxes[key].amount;
}
}
// custom fields w/o with taxes
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
total += roundToTwo(invoice.custom_value1);
@ -994,7 +1029,7 @@ function calculateAmounts(invoice) {
invoice.total_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
invoice.discount_amount = discount;
invoice.tax_amount = tax;
invoice.has_taxes = hasTaxes;
invoice.item_taxes = taxes;
if (NINJA.parseFloat(invoice.partial)) {
invoice.balance_amount = roundToTwo(invoice.partial);
@ -1039,11 +1074,12 @@ function displayInvoiceHeader(doc, invoice, layout) {
}
doc.text(totalX, layout.tableTop, invoiceLabels.line_total);
/*
if (invoice.has_taxes)
{
doc.text(taxX, layout.tableTop, invoiceLabels.tax);
}
*/
}
function displayInvoiceItems(doc, invoice, layout) {
@ -1226,10 +1262,11 @@ function displayInvoiceItems(doc, invoice, layout) {
doc.line(qtyX-45, y-16,qtyX-45, y+55);
/*
if (invoice.has_taxes) {
doc.line(taxX-15, y-16,taxX-15, y+55);
}
*/
doc.line(totalX-27, y-16,totalX-27, y+55);
}
@ -1292,9 +1329,11 @@ function displayInvoiceItems(doc, invoice, layout) {
doc.line(layout.descriptionLeft-8, topX,layout.descriptionLeft-8, y);
doc.line(layout.unitCostRight-55, topX,layout.unitCostRight-55, y);
doc.line(layout.qtyRight-50, topX,layout.qtyRight-50, y);
/*
if (invoice.has_taxes) {
doc.line(layout.taxRight-28, topX,layout.taxRight-28, y);
}
*/
doc.line(totalX-25, topX,totalX-25, y+90);
doc.line(totalX+45, topX,totalX+45, y+90);
}

View File

@ -599,7 +599,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -713,7 +713,6 @@ return array(
'add_to_invoice' => 'Zur Rechnung :invoice hinzufügen',
'create_new_invoice' => 'Neue Rechnung erstellen',
'task_errors' => 'Bitte korrigieren Sie alle überlappenden Zeiten',
'utf8_invoices' => 'Neue PDF Engine <sup>Beta</sup>',
'from' => 'Von',
'to' => 'An',
'font_size' => 'Schriftgrösse',

View File

@ -597,7 +597,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -569,7 +569,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -598,7 +598,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -590,7 +590,6 @@ return array(
'less_fields' => 'Moins de champs',
'client_name' => 'Nom du client',
'pdf_settings' => 'Réglages PDF',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Réglages du produit',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -590,7 +590,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -592,7 +592,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -600,7 +600,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -598,7 +598,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -593,7 +593,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -593,7 +593,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -596,7 +596,6 @@ return array(
'less_fields' => 'Less Fields',
'client_name' => 'Client Name',
'pdf_settings' => 'PDF Settings',
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
'product_settings' => 'Product Settings',
'auto_wrap' => 'Auto Line Wrap',
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',

View File

@ -3,13 +3,10 @@
@section('head')
@parent
<script src="{!! asset('js/pdf_viewer.js') !!}" type="text/javascript"></script>
<script src="{!! asset('js/compatibility.js') !!}" type="text/javascript"></script>
@if (Auth::user()->account->utf8_invoices)
<script src="{{ asset('js/pdf_viewer.js') }}" type="text/javascript"></script>
<script src="{{ asset('js/compatibility.js') }}" type="text/javascript"></script>
<script src="{{ asset('js/pdfmake.min.js') }}" type="text/javascript"></script>
<script src="{{ asset('js/vfs_fonts.js') }}" type="text/javascript"></script>
@endif
@stop
@ -102,10 +99,7 @@
{!! Former::select('invoice_design_id')->style('display:inline;width:120px')->fromQuery($invoiceDesigns, 'name', 'id') !!}
@endif
@if (Auth::user()->account->utf8_invoices)
{!! Former::text('font_size')->type('number')->min('0')->step('1')->style('width:120px') !!}
@endif
{!! Former::text('primary_color') !!}
{!! Former::text('secondary_color') !!}

View File

@ -23,7 +23,6 @@
{{ Former::populateField('custom_invoice_taxes2', intval($account->custom_invoice_taxes2)) }}
{{ Former::populateField('share_counter', intval($account->share_counter)) }}
{{ Former::populateField('pdf_email_attachment', intval($account->pdf_email_attachment)) }}
{{ Former::populateField('utf8_invoices', intval($account->utf8_invoices)) }}
<div class="row">
<div class="col-md-6">
@ -97,7 +96,6 @@
</div>
<div class="panel-body">
{!! Former::checkbox('pdf_email_attachment')->text(trans('texts.enable')) !!}
{!! Former::checkbox('utf8_invoices')->text(trans('texts.enable')) !!}
</div>
</div>
</div>

View File

@ -5,11 +5,8 @@
<script src="{{ asset('js/pdf_viewer.js') }}" type="text/javascript"></script>
<script src="{{ asset('js/compatibility.js') }}" type="text/javascript"></script>
@if (Auth::user()->account->utf8_invoices)
<script src="{{ asset('js/pdfmake.min.js') }}" type="text/javascript"></script>
<script src="{{ asset('js/vfs_fonts.js') }}" type="text/javascript"></script>
@endif
@stop
@ -138,7 +135,7 @@
<p>&nbsp;</p>
<div class="table-responsive">
<table class="table invoice-table" style="margin-bottom: 0px !important">
<table class="table invoice-table">
<thead>
<tr>
<th style="min-width:32px;" class="hide-border"></th>
@ -246,6 +243,15 @@
</tr>
@endif
<tr style="display:none" data-bind="visible: $root.invoice_item_taxes.show &amp;&amp; totals.hasItemTaxes">
<td class="hide-border" colspan="4"/>
@if (!$account->hide_quantity)
<td>{{ trans('texts.tax') }}</td>
@endif
<td style="min-width:120px"><span data-bind="html: totals.itemTaxRates"/></td>
<td style="text-align: right"><span data-bind="html: totals.itemTaxAmounts"/></td>
</tr>
<tr style="display:none" data-bind="visible: $root.invoice_taxes.show">
<td class="hide-border" colspan="3"/>
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
@ -1298,13 +1304,6 @@
var discount = self.totals.rawDiscounted();
total -= discount;
/*
var discount = parseFloat(self.discount());
if (discount > 0) {
total = roundToTwo(total * ((100 - discount)/100));
}
*/
var customValue1 = roundToTwo(self.custom_value1());
var customValue2 = roundToTwo(self.custom_value2());
var customTaxes1 = self.custom_taxes1() == 1;
@ -1326,6 +1325,65 @@
}
});
self.totals.itemTaxes = ko.computed(function() {
var taxes = {};
var total = self.totals.rawSubtotal();
for(var i=0; i<self.invoice_items().length; i++) {
var item = self.invoice_items()[i];
var lineTotal = item.totals.rawTotal();
if (self.discount()) {
if (parseInt(self.is_amount_discount())) {
lineTotal -= roundToTwo((lineTotal/total) * self.discount());
} else {
lineTotal -= roundToTwo(lineTotal * (self.discount()/100));
}
}
var taxAmount = roundToTwo(lineTotal * item.tax_rate() / 100);
if (taxAmount) {
var key = item.tax_name() + item.tax_rate();
if (taxes.hasOwnProperty(key)) {
taxes[key].amount += taxAmount;
} else {
taxes[key] = {name:item.tax_name(), rate:item.tax_rate(), amount:taxAmount};
}
}
}
return taxes;
});
self.totals.hasItemTaxes = ko.computed(function() {
var count = 0;
var taxes = self.totals.itemTaxes();
for (var key in taxes) {
if (taxes.hasOwnProperty(key)) {
count++;
}
}
return count > 0;
});
self.totals.itemTaxRates = ko.computed(function() {
var taxes = self.totals.itemTaxes();
var parts = [];
for (var key in taxes) {
if (taxes.hasOwnProperty(key)) {
parts.push(taxes[key].name + ' ' + (taxes[key].rate*1) + '%');
}
}
return parts.join('<br/>');
});
self.totals.itemTaxAmounts = ko.computed(function() {
var taxes = self.totals.itemTaxes();
var parts = [];
for (var key in taxes) {
if (taxes.hasOwnProperty(key)) {
parts.push(formatMoney(taxes[key].amount, self.client().currency_id()));
}
}
return parts.join('<br/>');
});
self.totals.rawPaidToDate = ko.computed(function() {
return accounting.toFixed(self.amount(),2) - accounting.toFixed(self.balance(),2);
});
@ -1357,6 +1415,13 @@
total = NINJA.parseFloat(total) + roundToTwo((total * (taxRate/100)));
}
var taxes = self.totals.itemTaxes();
for (var key in taxes) {
if (taxes.hasOwnProperty(key)) {
total += taxes[key].amount;
}
}
if (customValue1 && !customTaxes1) {
total = NINJA.parseFloat(total) + customValue1;
}
@ -1531,7 +1596,7 @@
read: function () {
var name = self.name() ? self.name() : '';
var rate = self.rate() ? parseFloat(self.rate()) + '%' : '';
return rate + name;
return name + ' ' + rate;
},
write: function (value) {
// do nothing
@ -1605,7 +1670,6 @@
if (data) {
ko.mapping.fromJS(data, self.mapping, this);
//if (this.cost()) this.cost(formatMoney(this.cost(), model ? model.invoice().currency_id() : 1, true));
}
self.wrapped_notes = ko.computed({
@ -1625,11 +1689,7 @@
this.totals.rawTotal = ko.computed(function() {
var cost = roundToTwo(NINJA.parseFloat(self.cost()));
var qty = roundToTwo(NINJA.parseFloat(self.qty()));
var taxRate = NINJA.parseFloat(self.tax_rate());
var value = cost * qty;
if (taxRate > 0) {
value += value * (taxRate/100);
}
return value ? roundToTwo(value) : 0;
});

View File

@ -5,12 +5,8 @@
<script src="{{ asset('js/pdf_viewer.js') }}" type="text/javascript"></script>
<script src="{{ asset('js/compatibility.js') }}" type="text/javascript"></script>
@if (Auth::user()->account->utf8_invoices)
<script src="{{ asset('js/pdfmake.min.js') }}" type="text/javascript"></script>
<script src="{{ asset('js/vfs_fonts.js') }}" type="text/javascript"></script>
@endif
<script>

View File

@ -7,11 +7,8 @@
<script src="{{ asset('js/pdf_viewer.js') }}" type="text/javascript"></script>
<script src="{{ asset('js/compatibility.js') }}" type="text/javascript"></script>
@if ($invoice->client->account->utf8_invoices)
<script src="{{ asset('js/pdfmake.min.js') }}" type="text/javascript"></script>
<script src="{{ asset('js/vfs_fonts.js') }}" type="text/javascript"></script>
@endif
<style type="text/css">
body {

View File

@ -136,6 +136,7 @@ table.table thead .sorting_desc_disabled:after { content: '' !important }
{!! Form::open(array('url' => 'get_started', 'id' => 'startForm')) !!}
{!! Form::hidden('guest_key') !!}
{!! Form::hidden('sign_up', Input::get('sign_up')) !!}
{!! Form::hidden('redirect_to', Input::get('redirect_to')) !!}
{!! Form::close() !!}
<script>

View File

@ -270,15 +270,11 @@
}
function ViewModel(data) {
console.log('== ViewModel ==');
console.log(data);
var self = this;
self.time_log = ko.observableArray();
if (data) {
data = JSON.parse(data.time_log);
console.log(data);
for (var i=0; i<data.length; i++) {
self.time_log.push(new TimeModel(data[i]));
}