diff --git a/.env.development.php b/.env.development.php
index a3a31df7b4f5..adeed69f24fa 100644
--- a/.env.development.php
+++ b/.env.development.php
@@ -4,6 +4,6 @@ return array(
//'TAG_MANAGER_KEY' => '',
//'ANALYTICS_KEY' => '',
- 'NINJA_PROD' => true,
+ //'NINJA_PROD' => true,
);
diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php
index 926b47f0bce6..7c257753e440 100755
--- a/app/controllers/AccountController.php
+++ b/app/controllers/AccountController.php
@@ -273,12 +273,16 @@ class AccountController extends \BaseController {
if (Auth::user()->account->isPro())
{
$account = Auth::user()->account;
- $account->custom_label1 = Input::get('custom_label1');
- $account->custom_value1 = Input::get('custom_value1');
- $account->custom_label2 = Input::get('custom_label2');
- $account->custom_value2 = Input::get('custom_value2');
- $account->custom_client_label1 = Input::get('custom_client_label1');
- $account->custom_client_label2 = Input::get('custom_client_label2');
+ $account->custom_label1 = trim(Input::get('custom_label1'));
+ $account->custom_value1 = trim(Input::get('custom_value1'));
+ $account->custom_label2 = trim(Input::get('custom_label2'));
+ $account->custom_value2 = trim(Input::get('custom_value2'));
+ $account->custom_client_label1 = trim(Input::get('custom_client_label1'));
+ $account->custom_client_label2 = trim(Input::get('custom_client_label2'));
+ $account->custom_invoice_label1 = trim(Input::get('custom_invoice_label1'));
+ $account->custom_invoice_label2 = trim(Input::get('custom_invoice_label2'));
+ $account->custom_invoice_taxes1 = Input::get('custom_invoice_taxes1') ? true : false;
+ $account->custom_invoice_taxes2 = Input::get('custom_invoice_taxes2') ? true : false;
$account->save();
Session::flash('message', trans('texts.updated_settings'));
@@ -292,6 +296,8 @@ class AccountController extends \BaseController {
if (Auth::user()->account->isPro())
{
$account = Auth::user()->account;
+ $account->hide_quantity = Input::get('hide_quantity') ? true : false;
+ $account->hide_paid_to_date = Input::get('hide_paid_to_date') ? true : false;
$account->primary_color = Input::get('primary_color');// ? Input::get('primary_color') : null;
$account->secondary_color = Input::get('secondary_color');// ? Input::get('secondary_color') : null;
$account->save();
diff --git a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php
index b5a5c31e2443..3ddc66d16b89 100755
--- a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php
+++ b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php
@@ -244,8 +244,8 @@ class ConfideSetupUsersTable extends Migration {
$t->unsignedInteger('country_id')->nullable();
$t->string('work_phone');
$t->text('private_notes');
- $t->decimal('balance', 13, 4);
- $t->decimal('paid_to_date', 13, 4);
+ $t->decimal('balance', 13, 2);
+ $t->decimal('paid_to_date', 13, 2);
$t->timestamp('last_login')->nullable();
$t->string('website');
$t->unsignedInteger('industry_id')->nullable();
@@ -326,10 +326,10 @@ class ConfideSetupUsersTable extends Migration {
$t->unsignedInteger('recurring_invoice_id')->index()->nullable();
$t->string('tax_name');
- $t->decimal('tax_rate', 13, 4);
+ $t->decimal('tax_rate', 13, 2);
- $t->decimal('amount', 13, 4);
- $t->decimal('balance', 13, 4);
+ $t->decimal('amount', 13, 2);
+ $t->decimal('balance', 13, 2);
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
$t->foreign('account_id')->references('id')->on('accounts');
@@ -375,7 +375,7 @@ class ConfideSetupUsersTable extends Migration {
$t->softDeletes();
$t->string('name');
- $t->decimal('rate', 13, 4);
+ $t->decimal('rate', 13, 2);
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
@@ -394,8 +394,8 @@ class ConfideSetupUsersTable extends Migration {
$t->string('product_key');
$t->text('notes');
- $t->decimal('cost', 13, 4);
- $t->decimal('qty', 13, 4);
+ $t->decimal('cost', 13, 2);
+ $t->decimal('qty', 13, 2);
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
@@ -417,11 +417,11 @@ class ConfideSetupUsersTable extends Migration {
$t->string('product_key');
$t->text('notes');
- $t->decimal('cost', 13, 4);
- $t->decimal('qty', 13, 4);
+ $t->decimal('cost', 13, 2);
+ $t->decimal('qty', 13, 2);
$t->string('tax_name');
- $t->decimal('tax_rate', 13, 4);
+ $t->decimal('tax_rate', 13, 2);
$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
$t->foreign('product_id')->references('id')->on('products');
@@ -446,7 +446,7 @@ class ConfideSetupUsersTable extends Migration {
$t->softDeletes();
$t->boolean('is_deleted');
- $t->decimal('amount', 13, 4);
+ $t->decimal('amount', 13, 2);
$t->date('payment_date');
$t->string('transaction_reference');
$t->string('payer_id');
@@ -473,8 +473,8 @@ class ConfideSetupUsersTable extends Migration {
$t->softDeletes();
$t->boolean('is_deleted');
- $t->decimal('amount', 13, 4);
- $t->decimal('balance', 13, 4);
+ $t->decimal('amount', 13, 2);
+ $t->decimal('balance', 13, 2);
$t->date('credit_date')->nullable();
$t->string('credit_number');
$t->text('private_notes');
@@ -504,8 +504,8 @@ class ConfideSetupUsersTable extends Migration {
$t->text('message');
$t->text('json_backup');
$t->integer('activity_type_id');
- $t->decimal('adjustment', 13, 4);
- $t->decimal('balance', 13, 4);
+ $t->decimal('adjustment', 13, 2);
+ $t->decimal('balance', 13, 2);
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
diff --git a/app/database/migrations/2014_07_17_205900_support_hiding_quantity.php b/app/database/migrations/2014_07_17_205900_support_hiding_quantity.php
new file mode 100644
index 000000000000..d055e4e908cb
--- /dev/null
+++ b/app/database/migrations/2014_07_17_205900_support_hiding_quantity.php
@@ -0,0 +1,66 @@
+boolean('hide_quantity');
+ $table->boolean('hide_paid_to_date');
+
+ $table->string('custom_invoice_label1');
+ $table->string('custom_invoice_label2');
+
+ $table->boolean('custom_invoice_taxes1');
+ $table->boolean('custom_invoice_taxes2');
+ });
+
+ Schema::table('invoices', function($table)
+ {
+ $table->decimal('custom_value1', 13, 2);
+ $table->decimal('custom_value2', 13, 2);
+
+ $table->boolean('custom_taxes1');
+ $table->boolean('custom_taxes2');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('accounts', function($table)
+ {
+ $table->dropColumn('hide_quantity');
+ $table->dropColumn('hide_paid_to_date');
+
+ $table->dropColumn('custom_invoice_label1');
+ $table->dropColumn('custom_invoice_label2');
+
+ $table->dropColumn('custom_invoice_taxes1');
+ $table->dropColumn('custom_invoice_taxes2');
+ });
+
+ Schema::table('invoices', function($table)
+ {
+ $table->dropColumn('custom_value1');
+ $table->dropColumn('custom_value2');
+
+ $table->dropColumn('custom_taxes1');
+ $table->dropColumn('custom_taxes2');
+ });
+ }
+
+}
diff --git a/app/filters.php b/app/filters.php
index ec8e64a3d218..0b28abcca26a 100755
--- a/app/filters.php
+++ b/app/filters.php
@@ -69,13 +69,17 @@ App::after(function($request, $response)
Route::filter('auth', function()
{
- if (Auth::guest()) {
- if(Utils::isNinja()) {
- return Redirect::guest('/');
- } else {
- return Redirect::guest('/login');
- }
+ if (Auth::guest())
+ {
+ if (Utils::isNinja() || Account::count() == 0)
+ {
+ return Redirect::guest('/');
+ }
+ else
+ {
+ return Redirect::guest('/login');
}
+ }
});
diff --git a/app/lang/de/texts.php b/app/lang/de/texts.php
index 50907c1a0976..2b81c45fb67c 100644
--- a/app/lang/de/texts.php
+++ b/app/lang/de/texts.php
@@ -45,7 +45,7 @@ return array(
'quantity' => 'Menge',
'line_total' => 'Summe',
'subtotal' => 'Zwischensumme',
- 'paid_to_date' => 'Zahlungsdatum',
+ 'paid_to_date' => 'Bereits gezahlt',
'balance_due' => 'Rechnungsbetrag',
'invoice_design_id' => 'Design',
'terms' => 'Bedingungen',
diff --git a/app/lang/en/texts.php b/app/lang/en/texts.php
index 2a254a89be30..b6504be860e1 100644
--- a/app/lang/en/texts.php
+++ b/app/lang/en/texts.php
@@ -397,6 +397,14 @@ return array(
'session_expired' => 'Your session has expired.',
+ 'invoice_fields' => 'Invoice Fields',
+ 'invoice_options' => 'Invoice Options',
+ 'hide_quantity' => 'Hide quantity',
+ 'hide_quantity_help' => 'All line items will have a quantity of one',
+ 'hide_paid_to_date' => 'Hide paid to date',
+ 'hide_paid_to_date_help' => 'Hide until a payment is made',
+
+ 'charge_taxes' => 'Charge taxes',
);
diff --git a/app/models/Invoice.php b/app/models/Invoice.php
index 29ac65b3a2ec..32a9dd0a7917 100755
--- a/app/models/Invoice.php
+++ b/app/models/Invoice.php
@@ -82,7 +82,11 @@ class Invoice extends EntityModel
'account',
'invoice_design_id',
'is_pro',
- 'is_quote']);
+ 'is_quote',
+ 'custom_value1',
+ 'custom_value2',
+ 'custom_taxes1',
+ 'custom_taxes2']);
$this->client->setVisible([
'name',
@@ -117,7 +121,9 @@ class Invoice extends EntityModel
'custom_client_label1',
'custom_client_label2',
'primary_color',
- 'secondary_color']);
+ 'secondary_color',
+ 'hide_quantity',
+ 'hide_paid_to_date']);
foreach ($this->invoice_items as $invoiceItem)
{
diff --git a/app/ninja/repositories/InvoiceRepository.php b/app/ninja/repositories/InvoiceRepository.php
index 1566b7f1c6a4..8dd1b80a7d39 100755
--- a/app/ninja/repositories/InvoiceRepository.php
+++ b/app/ninja/repositories/InvoiceRepository.php
@@ -237,7 +237,7 @@ class InvoiceRepository
foreach ($data['invoice_items'] as $item)
{
- if (!$item->cost && !$item->qty && !$item->product_key && !$item->notes)
+ if (!$item->cost && !$item->product_key && !$item->notes)
{
continue;
}
@@ -261,9 +261,30 @@ class InvoiceRepository
$total *= (100 - $invoice->discount) / 100;
}
+ $invoice->custom_value1 = $data['custom_value1'];
+ $invoice->custom_value2 = $data['custom_value2'];
+ $invoice->custom_taxes1 = $data['custom_taxes1'] ? true : false;
+ $invoice->custom_taxes2 = $data['custom_taxes2'] ? true : false;
+
+ // custom fields charged taxes
+ if ($invoice->custom_value1 && $invoice->custom_taxes1) {
+ $total += $invoice->custom_value1;
+ }
+ if ($invoice->custom_value2 && $invoice->custom_taxes2) {
+ $total += $invoice->custom_value2;
+ }
+
$total += $total * $invoice->tax_rate / 100;
$total = round($total, 2);
+ // custom fields not charged taxes
+ if ($invoice->custom_value1 && !$invoice->custom_taxes1) {
+ $total += $invoice->custom_value1;
+ }
+ if ($invoice->custom_value2 && !$invoice->custom_taxes2) {
+ $total += $invoice->custom_value2;
+ }
+
if ($publicId)
{
$invoice->balance = $total - ($invoice->amount - $invoice->balance);
@@ -280,7 +301,7 @@ class InvoiceRepository
foreach ($data['invoice_items'] as $item)
{
- if (!$item->cost && !$item->qty && !$item->product_key && !$item->notes)
+ if (!$item->cost && !$item->product_key && !$item->notes)
{
continue;
}
diff --git a/app/views/accounts/custom_fields.blade.php b/app/views/accounts/custom_fields.blade.php
index c791d23e1432..b856a5337995 100644
--- a/app/views/accounts/custom_fields.blade.php
+++ b/app/views/accounts/custom_fields.blade.php
@@ -6,6 +6,20 @@
{{ Former::open()->addClass('col-md-8 col-md-offset-2 warn-on-exit') }}
{{ Former::populate($account) }}
+ {{ Former::populateField('custom_invoice_taxes1', intval($account->custom_invoice_taxes1)) }}
+ {{ Former::populateField('custom_invoice_taxes2', intval($account->custom_invoice_taxes2)) }}
+
+ {{ Former::legend('invoice_fields') }}
+ {{ Former::text('custom_invoice_label1')->label(trans('texts.field_label'))
+ ->append(Former::checkbox('custom_invoice_taxes1')->raw() . ' ' . trans('texts.charge_taxes')) }}
+ {{ Former::text('custom_invoice_label2')->label(trans('texts.field_label'))
+ ->append(Former::checkbox('custom_invoice_taxes2')->raw() . ' ' . trans('texts.charge_taxes')) }}
+
+
+ {{ Former::legend('client_fields') }}
+ {{ Former::text('custom_client_label1')->label(trans('texts.field_label')) }}
+ {{ Former::text('custom_client_label2')->label(trans('texts.field_label')) }}
+
{{ Former::legend('company_fields') }}
{{ Former::text('custom_label1')->label(trans('texts.field_label')) }}
@@ -14,10 +28,6 @@
{{ Former::text('custom_label2')->label(trans('texts.field_label')) }}
{{ Former::text('custom_value2')->label(trans('texts.field_value')) }}
- {{ Former::legend('client_fields') }}
- {{ Former::text('custom_client_label1')->label(trans('texts.field_label')) }}
- {{ Former::text('custom_client_label2')->label(trans('texts.field_label')) }}
-
@if (Auth::user()->isPro())
{{ Former::actions( Button::lg_success_submit(trans('texts.save'))->append_with_icon('floppy-disk') ) }}
@else
diff --git a/app/views/accounts/invoice_design.blade.php b/app/views/accounts/invoice_design.blade.php
index 8839c3281a23..31c122e59ca4 100644
--- a/app/views/accounts/invoice_design.blade.php
+++ b/app/views/accounts/invoice_design.blade.php
@@ -6,6 +6,13 @@
{{ Former::open()->addClass('col-md-8 col-md-offset-2 warn-on-exit') }}
{{ Former::populate($account) }}
+ {{ Former::populateField('hide_quantity', intval($account->hide_quantity)) }}
+ {{ Former::populateField('hide_paid_to_date', intval($account->hide_paid_to_date)) }}
+
+ {{ Former::legend('invoice_options') }}
+ {{ Former::checkbox('hide_quantity')->text(trans('texts.hide_quantity_help')) }}
+ {{ Former::checkbox('hide_paid_to_date')->text(trans('texts.hide_paid_to_date_help')) }}
+
{{ Former::legend('invoice_design') }}
{{ Former::text('primary_color') }}
diff --git a/app/views/invoices/edit.blade.php b/app/views/invoices/edit.blade.php
index fe85616128c2..ad9270a0fed9 100755
--- a/app/views/invoices/edit.blade.php
+++ b/app/views/invoices/edit.blade.php
@@ -119,7 +119,7 @@
{{ trans('texts.item') }} |
{{ trans('texts.description') }} |
{{ trans('texts.unit_cost') }} |
- {{ trans('texts.quantity') }} |
+ {{ trans('texts.quantity') }} |
{{ trans('texts.tax') }} |
{{ trans('texts.line_total') }} |
|
@@ -140,7 +140,7 @@
|
-
+ |
|
@@ -154,10 +154,12 @@
|
+
+
|
-
+ |
{{ Former::textarea('public_notes')->data_bind("value: wrapped_notes, valueUpdate: 'afterkeydown'")
->label(false)->placeholder(trans('texts.note_to_client'))->style('resize: none') }}
@@ -169,35 +171,82 @@
|
|
- {{ trans('texts.subtotal') }} |
+ {{ trans('texts.subtotal') }} |
|
+
|
|
- {{ trans('texts.discount') }} |
+ {{ trans('texts.discount') }} |
|
+
+ @if (($account->custom_invoice_label1 || ($invoice && floatval($invoice->custom_value1)) != 0) && $account->custom_invoice_taxes1)
+
+ |
+ |
+ {{ $account->custom_invoice_label1 }} |
+ |
+
+ @endif
+
+ @if (($account->custom_invoice_label2 || ($invoice && floatval($invoice->custom_value2)) != 0) && $account->custom_invoice_taxes2)
+
+ |
+ |
+ {{ $account->custom_invoice_label2 }} |
+ |
+
+ @endif
+
|
|
- {{ trans('texts.tax') }} |
+ @if (!$account->hide_quantity)
+ {{ trans('texts.tax') }} |
+ @endif
|
|
+
+ @if (($account->custom_invoice_label1 || ($invoice && floatval($invoice->custom_value1)) != 0) && !$account->custom_invoice_taxes1)
+
+ |
+ |
+ {{ $account->custom_invoice_label1 }} |
+ |
+
+ @endif
+
+ @if (($account->custom_invoice_label2 || ($invoice && floatval($invoice->custom_value2)) != 0) && !$account->custom_invoice_taxes2)
+
+ |
+ |
+ {{ $account->custom_invoice_label2 }} |
+ |
+
+ @endif
+
+ @if (!$account->hide_paid_to_date)
+
+ |
+ |
+ {{ trans('texts.paid_to_date') }} |
+ |
+
+ @endif
+
|
|
- {{ trans('texts.paid_to_date') }} |
- |
-
-
- |
- |
- {{ trans($entityType == ENTITY_INVOICE ? 'texts.balance_due' : 'texts.total') }} |
+ {{ trans($entityType == ENTITY_INVOICE ? 'texts.balance_due' : 'texts.total') }} |
|
+
+
+
@@ -1017,6 +1066,11 @@
self.balance = ko.observable(0);
self.invoice_design_id = ko.observable({{ $account->invoice_design_id }});
+ self.custom_value1 = ko.observable(0);
+ self.custom_value2 = ko.observable(0);
+ self.custom_taxes1 = ko.observable(false);
+ self.custom_taxes2 = ko.observable(false);
+
self.mapping = {
'client': {
create: function(options) {
@@ -1037,6 +1091,9 @@
self.addItem = function() {
var itemModel = new ItemModel();
+ @if ($account->hide_quantity)
+ itemModel.qty(1);
+ @endif
self.invoice_items.push(itemModel);
applyComboboxListeners();
}
@@ -1044,6 +1101,8 @@
if (data) {
ko.mapping.fromJS(data, self.mapping, self);
self.is_recurring(parseInt(data.is_recurring));
+ self.is_recurring(parseInt(data.is_recurring) == 1);
+ self.is_recurring(parseInt(data.is_recurring) == 1);
} else {
self.addItem();
}
@@ -1125,12 +1184,24 @@
});
self.totals.taxAmount = ko.computed(function() {
- var total = self.totals.rawSubtotal();
+ var total = self.totals.rawSubtotal();
- var discount = parseFloat(self.discount());
- if (discount > 0) {
- total = roundToTwo(total * ((100 - discount)/100));
- }
+ 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;
+ var customTaxes2 = self.custom_taxes2() == 1;
+
+ if (customValue1 && customTaxes1) {
+ total = NINJA.parseFloat(total) + customValue1;
+ }
+ if (customValue2 && customTaxes2) {
+ total = NINJA.parseFloat(total) + customValue2;
+ }
var taxRate = parseFloat(self.tax_rate());
if (taxRate > 0) {
@@ -1158,11 +1229,30 @@
total = roundToTwo(total * ((100 - discount)/100));
}
+ var customValue1 = roundToTwo(self.custom_value1());
+ var customValue2 = roundToTwo(self.custom_value2());
+ var customTaxes1 = self.custom_taxes1() == 1;
+ var customTaxes2 = self.custom_taxes2() == 1;
+
+ if (customValue1 && customTaxes1) {
+ total = NINJA.parseFloat(total) + customValue1;
+ }
+ if (customValue2 && customTaxes2) {
+ total = NINJA.parseFloat(total) + customValue2;
+ }
+
var taxRate = parseFloat(self.tax_rate());
if (taxRate > 0) {
total = NINJA.parseFloat(total) + roundToTwo((total * (taxRate/100)));
}
+ if (customValue1 && !customTaxes1) {
+ total = NINJA.parseFloat(total) + customValue1;
+ }
+ if (customValue2 && !customTaxes2) {
+ total = NINJA.parseFloat(total) + customValue2;
+ }
+
var paid = self.totals.rawPaidToDate();
if (paid > 0) {
total -= paid;
@@ -1428,7 +1518,7 @@
}
this.isEmpty = function() {
- return !self.product_key() && !self.notes() && !self.cost() && !self.qty();
+ return !self.product_key() && !self.notes() && !self.cost() && (!self.qty() || {{ $account->hide_quantity ? 'true' : 'false' }});
}
this.onSelect = function(){
@@ -1508,6 +1598,9 @@
}
model.invoice().addItem();
//model.addTaxRate();
+ @else
+ model.invoice().custom_taxes1({{ $account->custom_invoice_taxes1 ? 'true' : 'false' }});
+ model.invoice().custom_taxes2({{ $account->custom_invoice_taxes2 ? 'true' : 'false' }});
@endif
// Add the first tax rate for new invoices
//if(model.invoice_taxes() && model.tax_rates().length > 0) {
@@ -1524,7 +1617,10 @@
}
onTaxRateChange();
+ // display blank instead of '0'
if (!model.invoice().discount()) model.invoice().discount('');
+ if (!model.invoice().custom_value1()) model.invoice().custom_value1('');
+ if (!model.invoice().custom_value2()) model.invoice().custom_value2('');
ko.applyBindings(model);
onItemChange();
diff --git a/public/built.css b/public/built.css
index e2c2b89ee4b6..7be4d1223df2 100644
--- a/public/built.css
+++ b/public/built.css
@@ -2269,6 +2269,12 @@ border-bottom-width: 1px;
.dashboard .table-striped>tbody>tr>td:first-child { padding-left: 15px; }
.dashboard .table-striped>thead>tr>th:first-child { padding-left: 15px; }
+
+.invoice-table tfoot input {
+ text-align: right;
+}
+
+
/***********************************************
New/edit invoice page
************************************************/
diff --git a/public/built.js b/public/built.js
index 63ad06573b34..27f2c933a153 100644
--- a/public/built.js
+++ b/public/built.js
@@ -47256,14 +47256,32 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
return;
}
- //var taxTitle = 'Tax ' + getInvoiceTaxRate(invoice) + '%';
var data = [
{'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
- {'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false},
- {'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false},
- {'paid_to_date': formatMoney(invoice.amount - invoice.balance, invoice.client.currency_id)}
+ {'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false}
];
+ if (NINJA.parseFloat(invoice.custom_value1) && NINJA.parseFloat(invoice.custom_taxes1)) {
+ data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) })
+ }
+ if (NINJA.parseFloat(invoice.custom_value2) && NINJA.parseFloat(invoice.custom_taxes2)) {
+ data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) })
+ }
+
+ data.push({'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false});
+
+ if (NINJA.parseFloat(invoice.custom_value1) && !NINJA.parseFloat(invoice.custom_taxes1)) {
+ data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) })
+ }
+ if (NINJA.parseFloat(invoice.custom_value2) && !NINJA.parseFloat(invoice.custom_taxes2)) {
+ data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) })
+ }
+
+ var paid = invoice.amount - invoice.balance;
+ if (invoice.account.hide_paid_to_date === '0' || paid) {
+ data.push({'paid_to_date': formatMoney(paid, invoice.client.currency_id)});
+ }
+
return displayGrid(doc, invoice, data, 300, y, layout, true, 550, rightAlignTitleX) + 10;
}
@@ -47410,11 +47428,18 @@ function calculateAmounts(invoice) {
invoice.subtotal_amount = total;
if (invoice.discount > 0) {
-
var discount = roundToTwo(total * (invoice.discount/100));
total -= discount;
}
+ // custom fields with taxes
+ if (NINJA.parseFloat(invoice.custom_value1) && NINJA.parseFloat(invoice.custom_taxes1)) {
+ total += roundToTwo(invoice.custom_value1);
+ }
+ if (NINJA.parseFloat(invoice.custom_value2) && NINJA.parseFloat(invoice.custom_taxes2)) {
+ total += roundToTwo(invoice.custom_value2);
+ }
+
var tax = 0;
if (invoice.tax && parseFloat(invoice.tax.rate)) {
tax = parseFloat(invoice.tax.rate);
@@ -47427,9 +47452,17 @@ function calculateAmounts(invoice) {
total = parseFloat(total) + parseFloat(tax);
}
+ // custom fields w/o with taxes
+ if (NINJA.parseFloat(invoice.custom_value1) && !NINJA.parseFloat(invoice.custom_taxes1)) {
+ total += roundToTwo(invoice.custom_value1);
+ }
+ if (NINJA.parseFloat(invoice.custom_value2) && !NINJA.parseFloat(invoice.custom_taxes2)) {
+ total += roundToTwo(invoice.custom_value2);
+ }
+
invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
- invoice.tax_amount = tax;
invoice.discount_amount = discount;
+ invoice.tax_amount = tax;
invoice.has_taxes = hasTaxes;
return invoice;
@@ -47455,7 +47488,9 @@ function displayInvoiceHeader(doc, invoice, layout) {
doc.text(layout.marginLeft, layout.tableTop, invoiceLabels.item);
doc.text(layout.descriptionLeft, layout.tableTop, invoiceLabels.description);
doc.text(costX, layout.tableTop, invoiceLabels.unit_cost);
- doc.text(qtyX, layout.tableTop, invoiceLabels.quantity);
+ if (invoice.account.hide_quantity === '0') {
+ doc.text(qtyX, layout.tableTop, invoiceLabels.quantity);
+ }
doc.text(totalX, layout.tableTop, invoiceLabels.line_total);
if (invoice.has_taxes)
@@ -47470,8 +47505,9 @@ function displayInvoiceItems(doc, invoice, layout) {
var line = 1;
var total = 0;
var shownItem = false;
- var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
+ var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
var tableTop = layout.tableTop;
+ var hideQuantity = invoice.account.hide_quantity === '1';
doc.setFontSize(8);
for (var i=0; itbody>tr>td:first-child { padding-left: 15px; }
.dashboard .table-striped>thead>tr>th:first-child { padding-left: 15px; }
+
+.invoice-table tfoot input {
+ text-align: right;
+}
+
+
/***********************************************
New/edit invoice page
************************************************/
diff --git a/public/js/script.js b/public/js/script.js
index 39e39bb472d3..f4e5b3a7deed 100644
--- a/public/js/script.js
+++ b/public/js/script.js
@@ -1331,14 +1331,32 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
return;
}
- //var taxTitle = 'Tax ' + getInvoiceTaxRate(invoice) + '%';
var data = [
{'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
- {'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false},
- {'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false},
- {'paid_to_date': formatMoney(invoice.amount - invoice.balance, invoice.client.currency_id)}
+ {'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false}
];
+ if (NINJA.parseFloat(invoice.custom_value1) && NINJA.parseFloat(invoice.custom_taxes1)) {
+ data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) })
+ }
+ if (NINJA.parseFloat(invoice.custom_value2) && NINJA.parseFloat(invoice.custom_taxes2)) {
+ data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) })
+ }
+
+ data.push({'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false});
+
+ if (NINJA.parseFloat(invoice.custom_value1) && !NINJA.parseFloat(invoice.custom_taxes1)) {
+ data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) })
+ }
+ if (NINJA.parseFloat(invoice.custom_value2) && !NINJA.parseFloat(invoice.custom_taxes2)) {
+ data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) })
+ }
+
+ var paid = invoice.amount - invoice.balance;
+ if (invoice.account.hide_paid_to_date === '0' || paid) {
+ data.push({'paid_to_date': formatMoney(paid, invoice.client.currency_id)});
+ }
+
return displayGrid(doc, invoice, data, 300, y, layout, true, 550, rightAlignTitleX) + 10;
}
@@ -1485,11 +1503,18 @@ function calculateAmounts(invoice) {
invoice.subtotal_amount = total;
if (invoice.discount > 0) {
-
var discount = roundToTwo(total * (invoice.discount/100));
total -= discount;
}
+ // custom fields with taxes
+ if (NINJA.parseFloat(invoice.custom_value1) && NINJA.parseFloat(invoice.custom_taxes1)) {
+ total += roundToTwo(invoice.custom_value1);
+ }
+ if (NINJA.parseFloat(invoice.custom_value2) && NINJA.parseFloat(invoice.custom_taxes2)) {
+ total += roundToTwo(invoice.custom_value2);
+ }
+
var tax = 0;
if (invoice.tax && parseFloat(invoice.tax.rate)) {
tax = parseFloat(invoice.tax.rate);
@@ -1502,9 +1527,17 @@ function calculateAmounts(invoice) {
total = parseFloat(total) + parseFloat(tax);
}
+ // custom fields w/o with taxes
+ if (NINJA.parseFloat(invoice.custom_value1) && !NINJA.parseFloat(invoice.custom_taxes1)) {
+ total += roundToTwo(invoice.custom_value1);
+ }
+ if (NINJA.parseFloat(invoice.custom_value2) && !NINJA.parseFloat(invoice.custom_taxes2)) {
+ total += roundToTwo(invoice.custom_value2);
+ }
+
invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
- invoice.tax_amount = tax;
invoice.discount_amount = discount;
+ invoice.tax_amount = tax;
invoice.has_taxes = hasTaxes;
return invoice;
@@ -1530,7 +1563,9 @@ function displayInvoiceHeader(doc, invoice, layout) {
doc.text(layout.marginLeft, layout.tableTop, invoiceLabels.item);
doc.text(layout.descriptionLeft, layout.tableTop, invoiceLabels.description);
doc.text(costX, layout.tableTop, invoiceLabels.unit_cost);
- doc.text(qtyX, layout.tableTop, invoiceLabels.quantity);
+ if (invoice.account.hide_quantity === '0') {
+ doc.text(qtyX, layout.tableTop, invoiceLabels.quantity);
+ }
doc.text(totalX, layout.tableTop, invoiceLabels.line_total);
if (invoice.has_taxes)
@@ -1545,8 +1580,9 @@ function displayInvoiceItems(doc, invoice, layout) {
var line = 1;
var total = 0;
var shownItem = false;
- var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
+ var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
var tableTop = layout.tableTop;
+ var hideQuantity = invoice.account.hide_quantity === '1';
doc.setFontSize(8);
for (var i=0; i