diff --git a/LICENSE b/LICENSE index 81e4a1266c5c..eaa9f1e3672c 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 dda7bdc85e62..b527e7ae48bd 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 70e1cbb639d6..52caaae72076 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 6e8696bfe87d..40c63ea30d9c 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 71870293bce2..74ba37fec136 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 54351d10c4e0..4d72f3ad1eed 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 99d84e7d387b..bd1b30a554e5 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 b1d5e79f70ae..752581c83783 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 ff2cf1b9920d..676fa142100b 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 264dd9c2e02f..68e9b52800fc 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 77eb85a0ec5f..43b28f4b9260 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 20a594bf2c4e..68fdefc62d14 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 60b8a25203cf..950e77bc9b89 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 4e02fde455ee..7a12139699e2 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 f15506d435cd..c900ee1db4bd 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 b5f7cad5bbc6..0d7687d4a8fe 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 cef04eb2dbeb..8624c3d9e91d 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 7cebf0efbd39..08e0c97b4d82 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 47aaefb211b9..1c5a0fc36a7d 100755 --- a/app/views/invoices/edit.blade.php +++ b/app/views/invoices/edit.blade.php @@ -165,16 +165,36 @@