diff --git a/LICENSE b/LICENSE index 81e4a1266c..eaa9f1e367 100644 --- a/LICENSE +++ b/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. diff --git a/app/commands/SendRecurringInvoices.php b/app/commands/SendRecurringInvoices.php index dda7bdc85e..b527e7ae48 100755 --- a/app/commands/SendRecurringInvoices.php +++ b/app/commands/SendRecurringInvoices.php @@ -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; diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 70e1cbb639..52caaae720 100755 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -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(); diff --git a/app/controllers/InvoiceApiController.php b/app/controllers/InvoiceApiController.php index 6e8696bfe8..40c63ea30d 100644 --- a/app/controllers/InvoiceApiController.php +++ b/app/controllers/InvoiceApiController.php @@ -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, diff --git a/app/lang/da/texts.php b/app/lang/da/texts.php index 71870293bc..74ba37fec1 100644 --- a/app/lang/da/texts.php +++ b/app/lang/da/texts.php @@ -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', ); diff --git a/app/lang/de/texts.php b/app/lang/de/texts.php index 54351d10c4..4d72f3ad1e 100644 --- a/app/lang/de/texts.php +++ b/app/lang/de/texts.php @@ -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', ); diff --git a/app/lang/en/texts.php b/app/lang/en/texts.php index 99d84e7d38..bd1b30a554 100644 --- a/app/lang/en/texts.php +++ b/app/lang/en/texts.php @@ -194,8 +194,8 @@ return array( 'email_paid' => 'Email me when an invoice is paid', '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 invoice terms', + 'default_email_footer' => 'Set default email signature', '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 invoice footer', + 'invoice_footer' => 'Invoice footer', + 'save_as_default_footer' => 'Save as default footer', ); diff --git a/app/lang/es/texts.php b/app/lang/es/texts.php index b1d5e79f70..752581c837 100644 --- a/app/lang/es/texts.php +++ b/app/lang/es/texts.php @@ -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', ); \ No newline at end of file diff --git a/app/lang/fr/texts.php b/app/lang/fr/texts.php index ff2cf1b992..676fa14210 100644 --- a/app/lang/fr/texts.php +++ b/app/lang/fr/texts.php @@ -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', ); \ No newline at end of file diff --git a/app/lang/it/texts.php b/app/lang/it/texts.php index 264dd9c2e0..68e9b52800 100644 --- a/app/lang/it/texts.php +++ b/app/lang/it/texts.php @@ -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', ); diff --git a/app/lang/lt/texts.php b/app/lang/lt/texts.php index 77eb85a0ec..43b28f4b92 100644 --- a/app/lang/lt/texts.php +++ b/app/lang/lt/texts.php @@ -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', ); diff --git a/app/lang/nb_NO/texts.php b/app/lang/nb_NO/texts.php index 20a594bf2c..68fdefc62d 100644 --- a/app/lang/nb_NO/texts.php +++ b/app/lang/nb_NO/texts.php @@ -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', ); \ No newline at end of file diff --git a/app/lang/nl/texts.php b/app/lang/nl/texts.php index 60b8a25203..950e77bc9b 100644 --- a/app/lang/nl/texts.php +++ b/app/lang/nl/texts.php @@ -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', ); \ No newline at end of file diff --git a/app/lang/pt_BR/texts.php b/app/lang/pt_BR/texts.php index 4e02fde455..7a12139699 100644 --- a/app/lang/pt_BR/texts.php +++ b/app/lang/pt_BR/texts.php @@ -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', ); diff --git a/app/models/Activity.php b/app/models/Activity.php index f15506d435..c900ee1db4 100755 --- a/app/models/Activity.php +++ b/app/models/Activity.php @@ -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(); } } diff --git a/app/models/Invoice.php b/app/models/Invoice.php index b5f7cad5bb..0d7687d4a8 100755 --- a/app/models/Invoice.php +++ b/app/models/Invoice.php @@ -77,6 +77,7 @@ class Invoice extends EntityModel 'invoice_date', 'due_date', 'terms', + 'invoice_footer', 'public_notes', 'amount', 'balance', diff --git a/app/ninja/repositories/InvoiceRepository.php b/app/ninja/repositories/InvoiceRepository.php index cef04eb2db..8624c3d9e9 100755 --- a/app/ninja/repositories/InvoiceRepository.php +++ b/app/ninja/repositories/InvoiceRepository.php @@ -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', diff --git a/app/views/accounts/notifications.blade.php b/app/views/accounts/notifications.blade.php index 7cebf0efbd..08e0c97b4d 100755 --- a/app/views/accounts/notifications.blade.php +++ b/app/views/accounts/notifications.blade.php @@ -37,7 +37,8 @@ {{ 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') ) }} diff --git a/app/views/invoices/edit.blade.php b/app/views/invoices/edit.blade.php index 47aaefb211..1c5a0fc36a 100755 --- a/app/views/invoices/edit.blade.php +++ b/app/views/invoices/edit.blade.php @@ -165,16 +165,36 @@