mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-08 12:12:48 +01:00
Enabled setting an invoice footer
This commit is contained in:
parent
dc117dbaff
commit
cfe01e7e05
3
LICENSE
3
LICENSE
@ -13,7 +13,8 @@ open-source software.
|
||||
|
||||
1. Redistributions of source code, in whole or part and with or without
|
||||
modification requires the express permission of the author and must prominently
|
||||
display "Powered by InvoiceNinja" in verifiable form with hyperlink to said site.
|
||||
display "Powered by InvoiceNinja" or the Invoice Ninja logo in verifiable form
|
||||
with hyperlink to said site.
|
||||
2. Neither the name nor any trademark of the Author may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
@ -53,6 +53,7 @@ class SendRecurringInvoices extends Command
|
||||
$invoice->po_number = $recurInvoice->po_number;
|
||||
$invoice->public_notes = $recurInvoice->public_notes;
|
||||
$invoice->terms = $recurInvoice->terms;
|
||||
$invoice->invoice_footer = $recurInvoice->invoice_footer;
|
||||
$invoice->tax_name = $recurInvoice->tax_name;
|
||||
$invoice->tax_rate = $recurInvoice->tax_rate;
|
||||
$invoice->invoice_design_id = $recurInvoice->invoice_design_id;
|
||||
|
@ -597,6 +597,7 @@ class AccountController extends \BaseController
|
||||
{
|
||||
$account = Auth::user()->account;
|
||||
$account->invoice_terms = Input::get('invoice_terms');
|
||||
$account->invoice_footer = Input::get('invoice_footer');
|
||||
$account->email_footer = Input::get('email_footer');
|
||||
$account->save();
|
||||
|
||||
|
@ -87,7 +87,8 @@ class InvoiceApiController extends Controller
|
||||
$fields = [
|
||||
'discount' => 0,
|
||||
'is_amount_discount' => false,
|
||||
'terms' => $account->invoice_terms,
|
||||
'terms' => '',
|
||||
'invoice_footer' => '',
|
||||
'public_notes' => '',
|
||||
'po_number' => '',
|
||||
'invoice_design_id' => $account->invoice_design_id,
|
||||
|
@ -535,5 +535,8 @@ return array(
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
'default_invoice_footer' => 'Set default invoice footer',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
);
|
||||
|
@ -525,5 +525,8 @@ return array(
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
'default_invoice_footer' => 'Set default invoice footer',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
);
|
||||
|
@ -194,8 +194,8 @@ return array(
|
||||
'email_paid' => 'Email me when an invoice is <b>paid</b>',
|
||||
'site_updates' => 'Site Updates',
|
||||
'custom_messages' => 'Custom Messages',
|
||||
'default_invoice_terms' => 'Set default invoice terms',
|
||||
'default_email_footer' => 'Set default email signature',
|
||||
'default_invoice_terms' => 'Set default <b>invoice terms</b>',
|
||||
'default_email_footer' => 'Set default <b>email signature</b>',
|
||||
'import_clients' => 'Import Client Data',
|
||||
'csv_file' => 'Select CSV file',
|
||||
'export_clients' => 'Export Client Data',
|
||||
@ -533,5 +533,8 @@ return array(
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
'default_invoice_footer' => 'Set default <b>invoice footer</b>',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
);
|
||||
|
@ -505,5 +505,8 @@ return array(
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
'default_invoice_footer' => 'Set default invoice footer',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
);
|
@ -525,6 +525,9 @@ return array(
|
||||
'order_overview' => 'Order overview',
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
|
||||
'default_invoice_footer' => 'Set default invoice footer',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
);
|
@ -528,5 +528,8 @@ return array(
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
'default_invoice_footer' => 'Set default invoice footer',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
);
|
||||
|
@ -536,6 +536,9 @@ return array(
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
'default_invoice_footer' => 'Set default invoice footer',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
);
|
||||
|
||||
|
@ -533,7 +533,10 @@ return array(
|
||||
'order_overview' => 'Order overview',
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
|
||||
'default_invoice_footer' => 'Set default invoice footer',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
|
||||
);
|
@ -529,6 +529,9 @@ return array(
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
'default_invoice_footer' => 'Set default invoice footer',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
|
||||
);
|
@ -516,5 +516,8 @@ return array(
|
||||
'match_address' => '*Address must match address accociated with credit card.',
|
||||
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
|
||||
|
||||
'default_invoice_footer' => 'Set default invoice footer',
|
||||
'invoice_footer' => 'Invoice footer',
|
||||
'save_as_default_footer' => 'Save as default footer',
|
||||
|
||||
);
|
||||
|
@ -177,26 +177,32 @@ class Activity extends Eloquent
|
||||
} else {
|
||||
$diff = floatval($invoice->amount) - floatval($invoice->getOriginal('amount'));
|
||||
|
||||
if ($diff == 0) {
|
||||
return;
|
||||
$fieldChanged = false;
|
||||
foreach (['invoice_number', 'po_number', 'invoice_date', 'due_date', 'terms', 'public_notes', 'invoice_footer'] as $field) {
|
||||
if ($invoice->$field != $invoice->getOriginal($field)) {
|
||||
$fieldChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$backupInvoice = Invoice::with('invoice_items', 'client.account', 'client.contacts')->find($invoice->id);
|
||||
if ($diff > 0 || $fieldChanged) {
|
||||
$backupInvoice = Invoice::with('invoice_items', 'client.account', 'client.contacts')->find($invoice->id);
|
||||
|
||||
if (!$invoice->is_quote && !$invoice->is_recurring) {
|
||||
$client->balance = $client->balance + $diff;
|
||||
$client->save();
|
||||
if ($diff > 0 && !$invoice->is_quote && !$invoice->is_recurring) {
|
||||
$client->balance = $client->balance + $diff;
|
||||
$client->save();
|
||||
}
|
||||
|
||||
$activity = Activity::getBlank($invoice);
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_UPDATE_QUOTE : ACTIVITY_TYPE_UPDATE_INVOICE;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'updated', $invoice);
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $invoice->is_quote || $invoice->is_recurring ? 0 : $diff;
|
||||
$activity->json_backup = $backupInvoice->hidePrivateFields()->toJSON();
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
$activity = Activity::getBlank($invoice);
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_UPDATE_QUOTE : ACTIVITY_TYPE_UPDATE_INVOICE;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'updated', $invoice);
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $invoice->is_quote || $invoice->is_recurring ? 0 : $diff;
|
||||
$activity->json_backup = $backupInvoice->hidePrivateFields()->toJSON();
|
||||
$activity->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ class Invoice extends EntityModel
|
||||
'invoice_date',
|
||||
'due_date',
|
||||
'terms',
|
||||
'invoice_footer',
|
||||
'public_notes',
|
||||
'amount',
|
||||
'balance',
|
||||
|
@ -221,6 +221,8 @@ class InvoiceRepository
|
||||
}
|
||||
}
|
||||
|
||||
$account = \Auth::user()->account;
|
||||
|
||||
$invoice->client_id = $data['client_id'];
|
||||
$invoice->discount = round(Utils::parseFloat($data['discount']), 2);
|
||||
$invoice->is_amount_discount = $data['is_amount_discount'] ? true : false;
|
||||
@ -240,7 +242,8 @@ class InvoiceRepository
|
||||
$invoice->end_date = null;
|
||||
}
|
||||
|
||||
$invoice->terms = trim($data['terms']);
|
||||
$invoice->terms = trim($data['terms']) ? trim($data['terms']) : $account->invoice_terms;
|
||||
$invoice->invoice_footer = trim($data['invoice_footer']) ? trim($data['invoice_footer']) : $account->invoice_footer;
|
||||
$invoice->public_notes = trim($data['public_notes']);
|
||||
$invoice->po_number = trim($data['po_number']);
|
||||
$invoice->invoice_design_id = $data['invoice_design_id'];
|
||||
@ -357,9 +360,14 @@ class InvoiceRepository
|
||||
$invoice->invoice_items()->save($invoiceItem);
|
||||
}
|
||||
|
||||
if (isset($data['set_default_terms']) && $data['set_default_terms']) {
|
||||
$account = \Auth::user()->account;
|
||||
$account->invoice_terms = $invoice->terms;
|
||||
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']) {
|
||||
$account->invoice_terms = trim($data['terms']);
|
||||
}
|
||||
if (isset($data['set_default_footer']) && $data['set_default_footer']) {
|
||||
$account->invoice_footer = trim($data['invoice_footer']);
|
||||
}
|
||||
$account->save();
|
||||
}
|
||||
|
||||
@ -400,6 +408,7 @@ class InvoiceRepository
|
||||
'start_date',
|
||||
'end_date',
|
||||
'terms',
|
||||
'invoice_footer',
|
||||
'public_notes',
|
||||
'invoice_design_id',
|
||||
'tax_name',
|
||||
|
@ -37,7 +37,8 @@
|
||||
</div></div>
|
||||
|
||||
{{ Former::legend('custom_messages') }}
|
||||
{{ Former::textarea('invoice_terms')->label(trans('texts.default_invoice_terms')) }}
|
||||
{{ Former::textarea('invoice_terms')->label(trans('texts.default_invoice_terms')) }}
|
||||
{{ Former::textarea('invoice_footer')->label(trans('texts.default_invoice_footer')) }}
|
||||
{{ Former::textarea('email_footer')->label(trans('texts.default_email_footer')) }}
|
||||
|
||||
{{ Former::actions( Button::lg_success_submit(trans('texts.save'))->append_with_icon('floppy-disk') ) }}
|
||||
|
@ -165,16 +165,36 @@
|
||||
<td class="hide-border"/>
|
||||
<td colspan="2" rowspan="6" style="vertical-align:top">
|
||||
<br/>
|
||||
{{ Former::textarea('public_notes')->data_bind("value: wrapped_notes, valueUpdate: 'afterkeydown'")
|
||||
->label(false)->placeholder(trans('texts.note_to_client'))->style('resize: none') }}
|
||||
{{ Former::textarea('terms')->data_bind("value: wrapped_terms, valueUpdate: 'afterkeydown'")
|
||||
->label(false)->placeholder(trans('texts.invoice_terms'))->style('resize: none')
|
||||
->addGroupClass('less-space-bottom') }}
|
||||
<label class="checkbox" style="width: 200px">
|
||||
<input type="checkbox" style="width: 24px" data-bind="checked: set_default_terms"/>{{ trans('texts.save_as_default_terms') }}
|
||||
</label>
|
||||
<div role="tabpanel">
|
||||
|
||||
<ul class="nav nav-tabs" role="tablist" style="border: none">
|
||||
<li role="presentation" class="active"><a href="#notes" aria-controls="notes" role="tab" data-toggle="tab">{{ trans('texts.note_to_client') }}</a></li>
|
||||
<li role="presentation"><a href="#terms" aria-controls="terms" role="tab" data-toggle="tab">{{ trans('texts.invoice_terms') }}</a></li>
|
||||
<li role="presentation"><a href="#footer" aria-controls="footer" role="tab" data-toggle="tab">{{ trans('texts.invoice_footer') }}</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="notes" style="padding-bottom:44px">
|
||||
{{ Former::textarea('public_notes')->data_bind("value: wrapped_notes, valueUpdate: 'afterkeydown'")
|
||||
->label(null)->style('resize: none; min-width: 460px;')->rows(3) }}
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="terms">
|
||||
{{ Former::textarea('terms')->data_bind("value:wrapped_terms, placeholder: default_terms, valueUpdate: 'afterkeydown'")
|
||||
->label(false)->style('resize: none; min-width: 460px')->rows(3)
|
||||
->help('<label class="checkbox" style="width: 200px">
|
||||
<input type="checkbox" style="width: 24px" data-bind="checked: set_default_terms"/>'.trans('texts.save_as_default_terms').'</label>') }}
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="footer">
|
||||
{{ Former::textarea('invoice_footer')->data_bind("value:wrapped_footer, placeholder: default_footer, valueUpdate: 'afterkeydown'")
|
||||
->label(false)->style('resize: none; min-width: 460px')->rows(3)
|
||||
->help('<label class="checkbox" style="width: 200px">
|
||||
<input type="checkbox" style="width: 24px" data-bind="checked: set_default_footer"/>'.trans('texts.save_as_default_footer').'</label>') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
<td style="display:none" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td class="hide-border" style="display:none" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="{{ $account->hide_quantity ? 1 : 2 }}">{{ trans('texts.subtotal') }}</td>
|
||||
<td style="text-align: right"><span data-bind="text: totals.subtotal"/></td>
|
||||
</tr>
|
||||
@ -243,7 +263,7 @@
|
||||
|
||||
<tr>
|
||||
<td class="hide-border" colspan="3"/>
|
||||
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td style="display:none" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="{{ $account->hide_quantity ? 1 : 2 }}"><b>{{ trans($entityType == ENTITY_INVOICE ? 'texts.balance_due' : 'texts.total') }}</b></td>
|
||||
<td style="text-align: right"><span data-bind="text: totals.total"/></td>
|
||||
</tr>
|
||||
@ -568,7 +588,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
$('#terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discount, #currency_id, #invoice_design_id, #recurring, #is_amount_discount').change(function() {
|
||||
$('#invoice_footer, #terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discount, #currency_id, #invoice_design_id, #recurring, #is_amount_discount').change(function() {
|
||||
setTimeout(function() {
|
||||
refreshPDF();
|
||||
}, 1);
|
||||
@ -618,8 +638,7 @@
|
||||
var client = model.invoice().client();
|
||||
setComboboxValue($('.client_select'),
|
||||
client.public_id(),
|
||||
client.name.display());
|
||||
|
||||
client.name.display());
|
||||
});
|
||||
|
||||
function applyComboboxListeners() {
|
||||
@ -653,6 +672,13 @@
|
||||
invoice.is_quote = {{ $entityType == ENTITY_QUOTE ? 'true' : 'false' }};
|
||||
invoice.contact = _.findWhere(invoice.client.contacts, {send_invoice: true});
|
||||
|
||||
if (!invoice.terms) {
|
||||
invoice.terms = "{{ $account->invoice_terms }}";
|
||||
}
|
||||
if (!invoice.invoice_footer) {
|
||||
invoice.invoice_footer = "{{ $account->invoice_footer }}";
|
||||
}
|
||||
|
||||
@if (file_exists($account->getLogoPath()))
|
||||
invoice.image = "{{ HTML::image_data($account->getLogoPath()) }}";
|
||||
invoice.imageWidth = {{ $account->getLogoWidth() }};
|
||||
@ -1025,8 +1051,12 @@
|
||||
self.is_amount_discount = ko.observable(0);
|
||||
self.frequency_id = ko.observable('');
|
||||
//self.currency_id = ko.observable({{ $client && $client->currency_id ? $client->currency_id : Session::get(SESSION_CURRENCY) }});
|
||||
self.terms = ko.observable(wordWrapText('{{ str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) }}', 300));
|
||||
self.set_default_terms = ko.observable(false);
|
||||
self.terms = ko.observable('');
|
||||
self.default_terms = ko.observable({{ $account->invoice_terms ? 'true' : 'false' }} ? wordWrapText('{{ str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) }}', 300) : "{{ trans('texts.invoice_terms') }}");
|
||||
self.set_default_terms = ko.observable(false);
|
||||
self.invoice_footer = ko.observable('');
|
||||
self.default_footer = ko.observable({{ $account->invoice_footer ? 'true' : 'false' }} ? wordWrapText('{{ str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_footer)) }}', 600) : "{{ trans('texts.invoice_footer') }}");
|
||||
self.set_default_footer = ko.observable(false);
|
||||
self.public_notes = ko.observable('');
|
||||
self.po_number = ko.observable('');
|
||||
self.invoice_date = ko.observable('{{ Utils::today() }}');
|
||||
@ -1102,31 +1132,37 @@
|
||||
|
||||
self.wrapped_terms = ko.computed({
|
||||
read: function() {
|
||||
$('#terms').height(this.terms().split('\n').length * 36);
|
||||
return this.terms();
|
||||
},
|
||||
write: function(value) {
|
||||
value = wordWrapText(value, 300);
|
||||
self.terms(value);
|
||||
$('#terms').height(value.split('\n').length * 36);
|
||||
},
|
||||
owner: this
|
||||
});
|
||||
|
||||
|
||||
self.wrapped_notes = ko.computed({
|
||||
read: function() {
|
||||
$('#public_notes').height(this.public_notes().split('\n').length * 36);
|
||||
return this.public_notes();
|
||||
},
|
||||
write: function(value) {
|
||||
value = wordWrapText(value, 300);
|
||||
self.public_notes(value);
|
||||
$('#public_notes').height(value.split('\n').length * 36);
|
||||
},
|
||||
owner: this
|
||||
});
|
||||
self.wrapped_notes = ko.computed({
|
||||
read: function() {
|
||||
return this.public_notes();
|
||||
},
|
||||
write: function(value) {
|
||||
value = wordWrapText(value, 300);
|
||||
self.public_notes(value);
|
||||
},
|
||||
owner: this
|
||||
});
|
||||
|
||||
self.wrapped_footer = ko.computed({
|
||||
read: function() {
|
||||
return this.invoice_footer();
|
||||
},
|
||||
write: function(value) {
|
||||
value = wordWrapText(value, 600);
|
||||
self.invoice_footer(value);
|
||||
},
|
||||
owner: this
|
||||
});
|
||||
|
||||
self.removeItem = function(item) {
|
||||
self.invoice_items.remove(item);
|
||||
|
@ -69,7 +69,7 @@
|
||||
} else {
|
||||
window.accountLogo = "{{ HTML::image_data($account->getLogoPath()) }}";
|
||||
}
|
||||
@endif
|
||||
@endif
|
||||
|
||||
var NINJA = NINJA || {};
|
||||
NINJA.primaryColor = "{{ $account->primary_color }}";
|
||||
|
@ -31603,6 +31603,16 @@ function GetPdf(invoice, javascript){
|
||||
|
||||
eval(javascript);
|
||||
|
||||
// add footer
|
||||
if (invoice.invoice_footer) {
|
||||
doc.setFontType('normal');
|
||||
doc.setFontSize('8');
|
||||
SetPdfColor('Black',doc);
|
||||
var top = doc.internal.pageSize.height - layout.marginLeft;
|
||||
var numLines = invoice.invoice_footer.split("\n").length - 1;
|
||||
doc.text(layout.marginLeft, top - (numLines * 8), invoice.invoice_footer);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
@ -31991,6 +32001,13 @@ if (window.ko) {
|
||||
if (value) $(element).datepicker('update', value);
|
||||
}
|
||||
};
|
||||
|
||||
ko.bindingHandlers.placeholder = {
|
||||
init: function (element, valueAccessor, allBindingsAccessor) {
|
||||
var underlyingObservable = valueAccessor();
|
||||
ko.applyBindingsToNode(element, { attr: { placeholder: underlyingObservable } } );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function wordWrapText(value, width)
|
||||
|
@ -80,6 +80,16 @@ function GetPdf(invoice, javascript){
|
||||
|
||||
eval(javascript);
|
||||
|
||||
// add footer
|
||||
if (invoice.invoice_footer) {
|
||||
doc.setFontType('normal');
|
||||
doc.setFontSize('8');
|
||||
SetPdfColor('Black',doc);
|
||||
var top = doc.internal.pageSize.height - layout.marginLeft;
|
||||
var numLines = invoice.invoice_footer.split("\n").length - 1;
|
||||
doc.text(layout.marginLeft, top - (numLines * 8), invoice.invoice_footer);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
@ -468,6 +478,13 @@ if (window.ko) {
|
||||
if (value) $(element).datepicker('update', value);
|
||||
}
|
||||
};
|
||||
|
||||
ko.bindingHandlers.placeholder = {
|
||||
init: function (element, valueAccessor, allBindingsAccessor) {
|
||||
var underlyingObservable = valueAccessor();
|
||||
ko.applyBindingsToNode(element, { attr: { placeholder: underlyingObservable } } );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function wordWrapText(value, width)
|
||||
|
Loading…
Reference in New Issue
Block a user