From 8049a27beb8f806af0ec2bea625e18da1a310781 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 21 May 2014 00:40:09 +0300 Subject: [PATCH] Working on quotes --- app/controllers/ClientController.php | 14 ++- app/controllers/DashboardController.php | 4 + app/controllers/InvoiceController.php | 117 ++++++++++-------- app/controllers/PaymentController.php | 9 +- app/controllers/QuoteController.php | 25 +++- app/controllers/ReportController.php | 7 ++ .../2014_05_17_175626_add_quotes.php | 6 + app/lang/de/texts.php | 53 +++++++- app/lang/en/texts.php | 38 +++++- app/lang/es/texts.php | 53 +++++++- app/lang/fr/texts.php | 54 +++++++- app/lang/it/texts.php | 54 +++++++- app/lang/nl/texts.php | 54 +++++++- app/lang/pt_BR/texts.php | 54 +++++++- app/libraries/utils.php | 21 ++-- app/models/Account.php | 5 + app/models/Activity.php | 57 ++++++--- app/models/Invoice.php | 5 +- app/ninja/mailers/ContactMailer.php | 4 +- app/ninja/mailers/UserMailer.php | 10 +- app/ninja/repositories/InvoiceRepository.php | 114 ++++++++++++++--- app/routes.php | 16 ++- app/views/clients/show.blade.php | 34 +++-- app/views/emails/invoice_html.blade.php | 2 +- app/views/emails/invoice_paid_html.blade.php | 4 +- app/views/emails/invoice_paid_text.blade.php | 4 +- app/views/emails/invoice_sent_html.blade.php | 2 +- app/views/emails/invoice_sent_text.blade.php | 2 +- app/views/emails/invoice_text.blade.php | 2 +- .../emails/invoice_viewed_html.blade.php | 2 +- .../emails/invoice_viewed_text.blade.php | 2 +- app/views/header.blade.php | 1 - app/views/invoices/edit.blade.php | 102 +++++++-------- app/views/invoices/view.blade.php | 4 +- app/views/plans.blade.php | 9 +- app/views/public/header.blade.php | 14 +++ public/built.js | 24 ++-- public/js/script.js | 24 ++-- 38 files changed, 756 insertions(+), 250 deletions(-) diff --git a/app/controllers/ClientController.php b/app/controllers/ClientController.php index cc34752075..ec52bc5774 100755 --- a/app/controllers/ClientController.php +++ b/app/controllers/ClientController.php @@ -82,8 +82,20 @@ class ClientController extends \BaseController { { $client = Client::withTrashed()->scope($publicId)->with('contacts', 'size', 'industry')->firstOrFail(); Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT); - + + $actionLinks = [ + [trans('texts.create_invoice'), URL::to('invoices/create/' . $client->public_id )], + [trans('texts.enter_payment'), URL::to('payments/create/' . $client->public_id )], + [trans('texts.enter_credit'), URL::to('credits/create/' . $client->public_id )] + ]; + + if (Utils::isPro()) + { + array_unshift($actionLinks, [trans('texts.create_quote'), URL::to('quotes/create/' . $client->public_id )]); + } + $data = array( + 'actionLinks' => $actionLinks, 'showBreadcrumbs' => false, 'client' => $client, 'credit' => $client->getTotalCredit(), diff --git a/app/controllers/DashboardController.php b/app/controllers/DashboardController.php index dd8cfd1cca..4e95368da2 100644 --- a/app/controllers/DashboardController.php +++ b/app/controllers/DashboardController.php @@ -35,11 +35,15 @@ class DashboardController extends \BaseController { $pastDue = Invoice::scope() ->where('due_date', '<', date('Y-m-d')) ->where('balance', '>', 0) + ->where('is_recurring', '=', false) + ->where('is_quote', '=', false) ->orderBy('due_date', 'asc')->take(6)->get(); $upcoming = Invoice::scope() ->where('due_date', '>', date('Y-m-d')) ->where('balance', '>', 0) + ->where('is_recurring', '=', false) + ->where('is_quote', '=', false) ->orderBy('due_date', 'asc')->take(6)->get(); $data = [ diff --git a/app/controllers/InvoiceController.php b/app/controllers/InvoiceController.php index 41193707e8..cc5e5eef33 100755 --- a/app/controllers/InvoiceController.php +++ b/app/controllers/InvoiceController.php @@ -125,16 +125,10 @@ class InvoiceController extends \BaseController { return View::make('invoices.view', $data); } - public function edit($publicId) + public function edit($publicId, $clone = false) { $invoice = Invoice::scope($publicId)->withTrashed()->with('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items')->firstOrFail(); - Utils::trackViewed($invoice->invoice_number . ' - ' . $invoice->client->getDisplayName(), ENTITY_INVOICE); - - $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); - $invoice->due_date = Utils::fromSqlDate($invoice->due_date); - $invoice->start_date = Utils::fromSqlDate($invoice->start_date); - $invoice->end_date = Utils::fromSqlDate($invoice->end_date); - $invoice->is_pro = Auth::user()->isPro(); + $entityType = $invoice->getEntityType(); $contactIds = DB::table('invitations') ->join('contacts', 'contacts.id', '=','invitations.contact_id') @@ -143,17 +137,38 @@ class InvoiceController extends \BaseController { ->where('invitations.deleted_at', '=', null) ->select('contacts.public_id')->lists('public_id'); + if ($clone) + { + $invoice->id = null; + $invoice->invoice_number = Auth::user()->account->getNextInvoiceNumber(); + $method = 'POST'; + $url = "{$entityType}s"; + } + else + { + Utils::trackViewed($invoice->invoice_number . ' - ' . $invoice->client->getDisplayName(), $invoice->getEntityType()); + $method = 'PUT'; + $url = "{$entityType}s/{$publicId}"; + } + + $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); + $invoice->due_date = Utils::fromSqlDate($invoice->due_date); + $invoice->start_date = Utils::fromSqlDate($invoice->start_date); + $invoice->end_date = Utils::fromSqlDate($invoice->end_date); + $invoice->is_pro = Auth::user()->isPro(); + $data = array( - 'showBreadcrumbs' => false, + 'entityType' => $entityType, + 'showBreadcrumbs' => $clone, 'account' => $invoice->account, 'invoice' => $invoice, 'data' => false, - 'method' => 'PUT', + 'method' => $method, 'invitationContactIds' => $contactIds, - 'url' => 'invoices/' . $publicId, - 'title' => '- ' . $invoice->invoice_number, + 'url' => $url, + 'title' => '- ' . trans("texts.edit_{$entityType}"), 'client' => $invoice->client); - $data = array_merge($data, self::getViewModel()); + $data = array_merge($data, self::getViewModel()); // Set the invitation link on the client's contacts $clients = $data['clients']; @@ -190,6 +205,7 @@ class InvoiceController extends \BaseController { } $data = array( + 'entityType' => ENTITY_INVOICE, 'account' => $account, 'invoice' => null, 'data' => Input::old('data'), @@ -206,7 +222,6 @@ class InvoiceController extends \BaseController { private static function getViewModel() { return [ - 'entityType' => ENTITY_INVOICE, 'account' => Auth::user()->account, 'products' => Product::scope()->orderBy('id')->get(array('product_key','notes','cost','qty')), 'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(), @@ -243,10 +258,11 @@ class InvoiceController extends \BaseController { private function save($publicId = null) { $action = Input::get('action'); - + $entityType = Input::get('entityType'); + if ($action == 'archive' || $action == 'delete') { - return InvoiceController::bulk(); + return InvoiceController::bulk($entityType); } $input = json_decode(Input::get('data')); @@ -257,7 +273,7 @@ class InvoiceController extends \BaseController { { Session::flash('error', trans('texts.invoice_error')); - return Redirect::to('invoices/create') + return Redirect::to("{$entityType}s/create") ->withInput()->withErrors($errors); } else @@ -269,7 +285,7 @@ class InvoiceController extends \BaseController { $invoiceData = (array) $invoice; $invoiceData['client_id'] = $client->id; - $invoice = $this->invoiceRepo->save($publicId, $invoiceData); + $invoice = $this->invoiceRepo->save($publicId, $invoiceData, $entityType); $account = Auth::user()->account; if ($account->invoice_taxes != $input->invoice_taxes @@ -311,7 +327,7 @@ class InvoiceController extends \BaseController { } } - $message = trans($publicId ? 'texts.updated_invoice' : 'texts.created_invoice'); + $message = trans($publicId ? "texts.updated_{$entityType}" : "texts.created_{$entityType}"); if ($input->invoice->client->public_id == '-1') { $message = $message . ' ' . trans('texts.and_created_client'); @@ -322,13 +338,17 @@ class InvoiceController extends \BaseController { if ($action == 'clone') { - return InvoiceController::cloneInvoice($publicId); + return $this->cloneInvoice($publicId); + } + else if ($action == 'convert') + { + return $this->convertQuote($publicId); } else if ($action == 'email') { if (Auth::user()->confirmed) { - $message = trans('texts.emailed_invoice'); + $message = trans("texts.emailed_{$entityType}"); $this->mailer->sendInvoice($invoice); Session::flash('message', $message); } @@ -344,7 +364,7 @@ class InvoiceController extends \BaseController { Session::flash('message', $message); } - $url = 'invoices/' . $invoice->public_id . '/edit'; + $url = "{$entityType}s/" . $invoice->public_id . '/edit'; return Redirect::to($url); } } @@ -379,7 +399,7 @@ class InvoiceController extends \BaseController { * @param int $id * @return Response */ - public function bulk() + public function bulk($entityType = ENTITY_INVOICE) { $action = Input::get('action'); $ids = Input::get('id') ? Input::get('id') : Input::get('ids'); @@ -387,44 +407,33 @@ class InvoiceController extends \BaseController { if ($count > 0) { - $message = Utils::pluralize('Successfully '.$action.'d ? invoice', $count); + $message = Utils::pluralize("{$action}d_{$entityType}", $count); Session::flash('message', $message); } - return Redirect::to('invoices'); + return Redirect::to("{$entityType}s"); } - public static function cloneInvoice($publicId) + public function convertQuote($publicId) { - $invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail(); + $invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail(); + $clone = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id); - $clone = Invoice::createNew(); - $clone->balance = $invoice->amount; - foreach (['client_id', 'discount', 'invoice_date', 'due_date', 'is_recurring', 'frequency_id', 'start_date', 'end_date', 'terms', 'public_notes', 'invoice_design_id', 'tax_name', 'tax_rate', 'amount'] as $field) - { - $clone->$field = $invoice->$field; - } - - if (!$clone->is_recurring) - { - $clone->invoice_number = Auth::user()->account->getNextInvoiceNumber(); - } - - $clone->save(); - - foreach ($invoice->invoice_items as $item) - { - $cloneItem = InvoiceItem::createNew(); - - foreach (['product_id', 'product_key', 'notes', 'cost', 'qty', 'tax_name', 'tax_rate'] as $field) - { - $cloneItem->$field = $item->$field; - } - - $clone->invoice_items()->save($cloneItem); - } - - Session::flash('message', trans('texts.cloned_invoice')); + Session::flash('message', trans('texts.converted_to_invoice')); return Redirect::to('invoices/' . $clone->public_id); } + + public function cloneInvoice($publicId) + { + /* + $invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail(); + $clone = $this->invoiceRepo->cloneInvoice($invoice); + $entityType = $invoice->getEntityType(); + + Session::flash('message', trans('texts.cloned_invoice')); + return Redirect::to("{$entityType}s/" . $clone->public_id); + */ + + return self::edit($publicId, true); + } } \ No newline at end of file diff --git a/app/controllers/PaymentController.php b/app/controllers/PaymentController.php index 648b2839b9..ee1ad83578 100755 --- a/app/controllers/PaymentController.php +++ b/app/controllers/PaymentController.php @@ -64,7 +64,8 @@ class PaymentController extends \BaseController 'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId, 'invoicePublicId' => Input::old('invoice') ? Input::old('invoice') : $invoicePublicId, 'invoice' => null, - 'invoices' => Invoice::scope()->with('client', 'invoice_status')->orderBy('invoice_number')->get(), + 'invoices' => Invoice::scope()->where('is_recurring', '=', false)->where('is_quote', '=', false) + ->with('client', 'invoice_status')->orderBy('invoice_number')->get(), 'payment' => null, 'method' => 'POST', 'url' => "payments", @@ -84,7 +85,8 @@ class PaymentController extends \BaseController $data = array( 'client' => null, 'invoice' => null, - 'invoices' => Invoice::scope()->with('client', 'invoice_status')->orderBy('invoice_number')->get(array('public_id','invoice_number')), + 'invoices' => Invoice::scope()->where('is_recurring', '=', false)->where('is_quote', '=', false) + ->with('client', 'invoice_status')->orderBy('invoice_number')->get(), 'payment' => $payment, 'method' => 'PUT', 'url' => 'payments/' . $publicId, @@ -116,12 +118,10 @@ class PaymentController extends \BaseController $gateway->$function($val); } - /* if (!Utils::isProd()) { $gateway->setTestMode(true); } - */ return $gateway; } @@ -307,7 +307,6 @@ class PaymentController extends \BaseController $client->save(); } - try { if($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) diff --git a/app/controllers/QuoteController.php b/app/controllers/QuoteController.php index 0f51c9b21f..2024724123 100644 --- a/app/controllers/QuoteController.php +++ b/app/controllers/QuoteController.php @@ -24,6 +24,11 @@ class QuoteController extends \BaseController { public function index() { + if (!Utils::isPro()) + { + return Redirect::to('/invoices/create'); + } + $data = [ 'title' => '- Quotes', 'entityType'=>ENTITY_QUOTE, @@ -49,6 +54,11 @@ class QuoteController extends \BaseController { public function create($clientPublicId = 0) { + if (!Utils::isPro()) + { + return Redirect::to('/invoices/create'); + } + $client = null; $invoiceNumber = Auth::user()->account->getNextInvoiceNumber(); $account = Account::with('country')->findOrFail(Auth::user()->account_id); @@ -64,7 +74,7 @@ class QuoteController extends \BaseController { 'data' => Input::old('data'), 'invoiceNumber' => $invoiceNumber, 'method' => 'POST', - 'url' => 'quotes', + 'url' => 'invoices', 'title' => '- New Quote', 'client' => $client); $data = array_merge($data, self::getViewModel()); @@ -90,5 +100,18 @@ class QuoteController extends \BaseController { ]; } + public function bulk() + { + $action = Input::get('action'); + $ids = Input::get('id') ? Input::get('id') : Input::get('ids'); + $count = $this->invoiceRepo->bulk($ids, $action); + if ($count > 0) + { + $message = Utils::pluralize("{$action}d_quote", $count); + Session::flash('message', $message); + } + + return Redirect::to('quotes'); + } } \ No newline at end of file diff --git a/app/controllers/ReportController.php b/app/controllers/ReportController.php index 8404f839e6..a4a07aa53e 100755 --- a/app/controllers/ReportController.php +++ b/app/controllers/ReportController.php @@ -32,11 +32,18 @@ class ReportController extends \BaseController { { $records = DB::table($entityType.'s') ->select(DB::raw('sum(amount) as total, '.$groupBy.'('.$entityType.'_date) as '.$groupBy)) + ->where('account_id', '=', Auth::user()->account_id) ->where($entityType.'s.deleted_at', '=', null) ->where($entityType.'s.'.$entityType.'_date', '>=', $startDate->format('Y-m-d')) ->where($entityType.'s.'.$entityType.'_date', '<=', $endDate->format('Y-m-d')) ->groupBy($groupBy); + if ($entityType == ENTITY_INVOICE) + { + $records->where('is_quote', '=', false) + ->where('is_recurring', '=', false); + } + $totals = $records->lists('total'); $dates = $records->lists($groupBy); $data = array_combine($dates, $totals); diff --git a/app/database/migrations/2014_05_17_175626_add_quotes.php b/app/database/migrations/2014_05_17_175626_add_quotes.php index 5db67cb83f..ae3059c321 100644 --- a/app/database/migrations/2014_05_17_175626_add_quotes.php +++ b/app/database/migrations/2014_05_17_175626_add_quotes.php @@ -15,6 +15,9 @@ class AddQuotes extends Migration { Schema::table('invoices', function($table) { $table->boolean('is_quote'); + + $table->unsignedInteger('quote_id')->nullable(); + $table->unsignedInteger('quote_invoice_id')->nullable(); }); } @@ -28,6 +31,9 @@ class AddQuotes extends Migration { Schema::table('invoices', function($table) { $table->dropColumn('is_quote'); + + $table->dropColumn('quote_id'); + $table->dropColumn('quote_invoice_id'); }); } diff --git a/app/lang/de/texts.php b/app/lang/de/texts.php index 80994e330d..57c9e94a7c 100644 --- a/app/lang/de/texts.php +++ b/app/lang/de/texts.php @@ -260,12 +260,12 @@ return array( 'email_from' => 'Das InvoiceNinja Team', 'user_email_footer' => 'Um deine E-Mail Benachrichtigungen anzupassen besuche bitte '.SITE_URL.'/company/notifications', 'invoice_link_message' => 'Um deine Kundenrechnung anzuschauen, klicke auf den folgenden Link:', - 'notification_paid_subject' => 'Die Rechnung :invoice wurde von :client bezahlt', - 'notification_sent_subject' => 'Die Rechnung :invoice wurde an :client versendet', - 'notification_viewed_subject' => 'Die Rechnung :invoice wurde von :client angeschaut', - 'notification_paid' => 'Eine Zahlung von :amount wurde von :client bezüglich Rechnung :invoice getätigt.', - 'notification_sent' => 'Dem folgenden Kunden :client wurde die Rechnung :invoice über :amount zugesendet.', - 'notification_viewed' => 'Der folgende Kunde :client hat sich Rechnung :invoice über :amount angesehen.', + 'notification_invoice_paid_subject' => 'Die Rechnung :invoice wurde von :client bezahlt', + 'notification_invoice_sent_subject' => 'Die Rechnung :invoice wurde an :client versendet', + 'notification_invoice_viewed_subject' => 'Die Rechnung :invoice wurde von :client angeschaut', + 'notification_invoice_paid' => 'Eine Zahlung von :amount wurde von :client bezüglich Rechnung :invoice getätigt.', + 'notification_invoice_sent' => 'Dem folgenden Kunden :client wurde die Rechnung :invoice über :amount zugesendet.', + 'notification_invoice_viewed' => 'Der folgende Kunde :client hat sich Rechnung :invoice über :amount angesehen.', 'reset_password' => 'Du kannst dein Passwort zurücksetzen indem du auf den folgenden Link klickst:', 'reset_password_footer' => 'Wenn du das Zurücksetzen des Passworts nicht beantragt hast benachrichtige bitte unseren Support: ' . CONTACT_EMAIL, @@ -338,4 +338,45 @@ return array( 'ninja_email_footer' => 'Use :site to invoice your clients and get paid online for free!', + // Quotes + 'quote' => 'Quote', + 'quotes' => 'Quotes', + 'quote_number' => 'Quote Number', + 'quote_number_short' => 'Quote #', + 'quote_date' => 'Quote Date', + 'quote_total' => 'Quote Total', + 'your_quote' => 'Your Quote', + 'total' => 'Total', + 'clone' => 'Clone', + + 'new_quote' => 'New Quote', + 'create_quote' => 'Create Quote', + 'edit_quote' => 'Edit Quote', + 'archive_quote' => 'Archive Quote', + 'delete_quote' => 'Delete Quote', + 'save_quote' => 'Save Quote', + 'email_quote' => 'Email Quote', + 'clone_quote' => 'Clone Quote', + 'convert_to_invoice' => 'Convert to Invoice', + 'view_invoice' => 'View Invoice', + 'view_quote' => 'View Quote', + + 'updated_quote' => 'Successfully updated quote', + 'created_quote' => 'Successfully created quote', + 'cloned_quote' => 'Successfully cloned quote', + 'emailed_quote' => 'Successfully emailed quote', + 'archived_quote' => 'Successfully archived quote', + 'archived_quotes' => 'Successfully archived :count quotes', + 'deleted_quote' => 'Successfully deleted quote', + 'deleted_quotes' => 'Successfully deleted :count quotes', + 'converted_to_invoice' => 'Successfully converted quote to invoice', + + 'quote_subject' => 'New quote from :account', + 'quote_message' => 'To view your quote for :amount, click the link below.', + 'quote_link_message' => 'To view your client quote click the link below:', + 'notification_quote_sent_subject' => 'Quote :invoice was sent to :client', + 'notification_quote_viewed_subject' => 'Quote :invoice was viewed by :client', + 'notification_quote_sent' => 'The following client :client was emailed Quote :invoice for :amount.', + 'notification_quote_viewed' => 'The following client :client viewed Quote :invoice for :amount.', + ); diff --git a/app/lang/en/texts.php b/app/lang/en/texts.php index fe421a2a62..f09d1d300a 100644 --- a/app/lang/en/texts.php +++ b/app/lang/en/texts.php @@ -262,15 +262,16 @@ return array( 'email_from' => 'The InvoiceNinja Team', 'user_email_footer' => 'To adjust your email notification settings please visit '.SITE_URL.'/company/notifications', 'invoice_link_message' => 'To view your client invoice click the link below:', - 'notification_paid_subject' => 'Invoice :invoice was paid by :client', - 'notification_sent_subject' => 'Invoice :invoice was sent to :client', - 'notification_viewed_subject' => 'Invoice :invoice was viewed by :client', - 'notification_paid' => 'A payment of :amount was made by client :client towards Invoice :invoice.', - 'notification_sent' => 'The following client :client was emailed Invoice :invoice for :amount.', - 'notification_viewed' => 'The following client :client viewed Invoice :invoice for :amount.', + 'notification_invoice_paid_subject' => 'Invoice :invoice was paid by :client', + 'notification_invoice_sent_subject' => 'Invoice :invoice was sent to :client', + 'notification_invoice_viewed_subject' => 'Invoice :invoice was viewed by :client', + 'notification_invoice_paid' => 'A payment of :amount was made by client :client towards Invoice :invoice.', + 'notification_invoice_sent' => 'The following client :client was emailed Invoice :invoice for :amount.', + 'notification_invoice_viewed' => 'The following client :client viewed Invoice :invoice for :amount.', 'reset_password' => 'You can reset your account password by clicking the following link:', 'reset_password_footer' => 'If you did not request this password reset please email our support: ' . CONTACT_EMAIL, + // Payment page 'secure_payment' => 'Secure Payment', 'card_number' => 'Card number', @@ -351,16 +352,29 @@ return array( 'chart_builder' => 'Chart Builder', 'ninja_email_footer' => 'Use :site to invoice your clients and get paid online for free!', + + // Quotes 'quote' => 'Quote', 'quotes' => 'Quotes', 'quote_number' => 'Quote Number', + 'quote_number_short' => 'Quote #', 'quote_date' => 'Quote Date', 'quote_total' => 'Quote Total', + 'your_quote' => 'Your Quote', + 'total' => 'Total', + 'clone' => 'Clone', 'new_quote' => 'New Quote', + 'create_quote' => 'Create Quote', 'edit_quote' => 'Edit Quote', 'archive_quote' => 'Archive Quote', 'delete_quote' => 'Delete Quote', + 'save_quote' => 'Save Quote', + 'email_quote' => 'Email Quote', + 'clone_quote' => 'Clone Quote', + 'convert_to_invoice' => 'Convert to Invoice', + 'view_invoice' => 'View Invoice', + 'view_quote' => 'View Quote', 'updated_quote' => 'Successfully updated quote', 'created_quote' => 'Successfully created quote', @@ -370,6 +384,18 @@ return array( 'archived_quotes' => 'Successfully archived :count quotes', 'deleted_quote' => 'Successfully deleted quote', 'deleted_quotes' => 'Successfully deleted :count quotes', + 'converted_to_invoice' => 'Successfully converted quote to invoice', + + 'quote_subject' => 'New quote from :account', + 'quote_message' => 'To view your quote for :amount, click the link below.', + 'quote_link_message' => 'To view your client quote click the link below:', + 'notification_quote_sent_subject' => 'Quote :invoice was sent to :client', + 'notification_quote_viewed_subject' => 'Quote :invoice was viewed by :client', + 'notification_quote_sent' => 'The following client :client was emailed Quote :invoice for :amount.', + 'notification_quote_viewed' => 'The following client :client viewed Quote :invoice for :amount.', + + + ); diff --git a/app/lang/es/texts.php b/app/lang/es/texts.php index b03704badd..40b8fd5c39 100644 --- a/app/lang/es/texts.php +++ b/app/lang/es/texts.php @@ -261,12 +261,12 @@ return array( 'email_from' => 'The InvoiceNinja Team', 'user_email_footer' => 'To adjust your email notification settings please visit '.SITE_URL.'/company/notifications', 'invoice_link_message' => 'To view your client invoice click the link below:', - 'notification_paid_subject' => 'Invoice :invoice was paid by :client', - 'notification_sent_subject' => 'Invoice :invoice was sent to :client', - 'notification_viewed_subject' => 'Invoice :invoice was viewed by :client', - 'notification_paid' => 'A payment of :amount was made by client :client towards Invoice :invoice.', - 'notification_sent' => 'The following client :client was emailed Invoice :invoice for :amount.', - 'notification_viewed' => 'The following client :client viewed Invoice :invoice for :amount.', + 'notification_invoice_paid_subject' => 'Invoice :invoice was paid by :client', + 'notification_invoice_sent_subject' => 'Invoice :invoice was sent to :client', + 'notification_invoice_viewed_subject' => 'Invoice :invoice was viewed by :client', + 'notification_invoice_paid' => 'A payment of :amount was made by client :client towards Invoice :invoice.', + 'notification_invoice_sent' => 'The following client :client was emailed Invoice :invoice for :amount.', + 'notification_invoice_viewed' => 'The following client :client viewed Invoice :invoice for :amount.', 'reset_password' => 'You can reset your account password by clicking the following link:', 'reset_password_footer' => 'If you did not request this password reset please email our support: ' . CONTACT_EMAIL, @@ -335,5 +335,46 @@ return array( 'chart_builder' => 'Chart Builder', 'ninja_email_footer' => 'Use :site to invoice your clients and get paid online for free!', + + // Quotes + 'quote' => 'Quote', + 'quotes' => 'Quotes', + 'quote_number' => 'Quote Number', + 'quote_number_short' => 'Quote #', + 'quote_date' => 'Quote Date', + 'quote_total' => 'Quote Total', + 'your_quote' => 'Your Quote', + 'total' => 'Total', + 'clone' => 'Clone', + + 'new_quote' => 'New Quote', + 'create_quote' => 'Create Quote', + 'edit_quote' => 'Edit Quote', + 'archive_quote' => 'Archive Quote', + 'delete_quote' => 'Delete Quote', + 'save_quote' => 'Save Quote', + 'email_quote' => 'Email Quote', + 'clone_quote' => 'Clone Quote', + 'convert_to_invoice' => 'Convert to Invoice', + 'view_invoice' => 'View Invoice', + 'view_quote' => 'View Quote', + + 'updated_quote' => 'Successfully updated quote', + 'created_quote' => 'Successfully created quote', + 'cloned_quote' => 'Successfully cloned quote', + 'emailed_quote' => 'Successfully emailed quote', + 'archived_quote' => 'Successfully archived quote', + 'archived_quotes' => 'Successfully archived :count quotes', + 'deleted_quote' => 'Successfully deleted quote', + 'deleted_quotes' => 'Successfully deleted :count quotes', + 'converted_to_invoice' => 'Successfully converted quote to invoice', + + 'quote_subject' => 'New quote from :account', + 'quote_message' => 'To view your quote for :amount, click the link below.', + 'quote_link_message' => 'To view your client quote click the link below:', + 'notification_quote_sent_subject' => 'Quote :invoice was sent to :client', + 'notification_quote_viewed_subject' => 'Quote :invoice was viewed by :client', + 'notification_quote_sent' => 'The following client :client was emailed Quote :invoice for :amount.', + 'notification_quote_viewed' => 'The following client :client viewed Quote :invoice for :amount.', ); diff --git a/app/lang/fr/texts.php b/app/lang/fr/texts.php index d3f677279d..caf5f0a538 100644 --- a/app/lang/fr/texts.php +++ b/app/lang/fr/texts.php @@ -262,12 +262,12 @@ return array( 'email_from' => 'L\'équipe InvoiceNinja', 'user_email_footer' => 'Pour modifier vos paramètres de notification par email, veuillez visiter '.SITE_URL.'/company/notifications', 'invoice_link_message' => 'Pour voir la facture de votre client cliquez sur le lien ci-après :', - 'notification_paid_subject' => 'La facture :invoice a été payée par le client :client', - 'notification_sent_subject' => 'La facture :invoice a été envoyée au client :client', - 'notification_viewed_subject' => 'La facture :invoice a été vue par le client :client', - 'notification_paid' => 'Un paiement de :amount a été effectué par le client :client concernant la facture :invoice.', - 'notification_sent' => 'Le client suivant :client a reçu par email la facture :invoice d\'un montant de :amount', - 'notification_viewed' => 'Le client suivant :client a vu la facture :invoice d\'un montant de :amount', + 'notification_invoice_paid_subject' => 'La facture :invoice a été payée par le client :client', + 'notification_invoice_sent_subject' => 'La facture :invoice a été envoyée au client :client', + 'notification_invoice_viewed_subject' => 'La facture :invoice a été vue par le client :client', + 'notification_invoice_paid' => 'Un paiement de :amount a été effectué par le client :client concernant la facture :invoice.', + 'notification_invoice_sent' => 'Le client suivant :client a reçu par email la facture :invoice d\'un montant de :amount', + 'notification_invoice_viewed' => 'Le client suivant :client a vu la facture :invoice d\'un montant de :amount', 'reset_password' => 'Vous pouvez réinitialiser votre mot de passe en cliquant sur le lien suivant :', 'reset_password_footer' => 'Si vous n\'avez pas effectué de demande de réinitalisation de mot de passe veuillez contacter notre support :' . CONTACT_EMAIL, @@ -336,5 +336,47 @@ return array( 'chart_builder' => 'Chart Builder', 'ninja_email_footer' => 'Use :site to invoice your clients and get paid online for free!', + + + // Quotes + 'quote' => 'Quote', + 'quotes' => 'Quotes', + 'quote_number' => 'Quote Number', + 'quote_number_short' => 'Quote #', + 'quote_date' => 'Quote Date', + 'quote_total' => 'Quote Total', + 'your_quote' => 'Your Quote', + 'total' => 'Total', + 'clone' => 'Clone', + + 'new_quote' => 'New Quote', + 'create_quote' => 'Create Quote', + 'edit_quote' => 'Edit Quote', + 'archive_quote' => 'Archive Quote', + 'delete_quote' => 'Delete Quote', + 'save_quote' => 'Save Quote', + 'email_quote' => 'Email Quote', + 'clone_quote' => 'Clone Quote', + 'convert_to_invoice' => 'Convert to Invoice', + 'view_invoice' => 'View Invoice', + 'view_quote' => 'View Quote', + + 'updated_quote' => 'Successfully updated quote', + 'created_quote' => 'Successfully created quote', + 'cloned_quote' => 'Successfully cloned quote', + 'emailed_quote' => 'Successfully emailed quote', + 'archived_quote' => 'Successfully archived quote', + 'archived_quotes' => 'Successfully archived :count quotes', + 'deleted_quote' => 'Successfully deleted quote', + 'deleted_quotes' => 'Successfully deleted :count quotes', + 'converted_to_invoice' => 'Successfully converted quote to invoice', + + 'quote_subject' => 'New quote from :account', + 'quote_message' => 'To view your quote for :amount, click the link below.', + 'quote_link_message' => 'To view your client quote click the link below:', + 'notification_quote_sent_subject' => 'Quote :invoice was sent to :client', + 'notification_quote_viewed_subject' => 'Quote :invoice was viewed by :client', + 'notification_quote_sent' => 'The following client :client was emailed Quote :invoice for :amount.', + 'notification_quote_viewed' => 'The following client :client viewed Quote :invoice for :amount.', ); diff --git a/app/lang/it/texts.php b/app/lang/it/texts.php index bba41f289c..51499dc200 100644 --- a/app/lang/it/texts.php +++ b/app/lang/it/texts.php @@ -262,12 +262,12 @@ return array( 'email_from' => 'Il Team di InvoiceNinja', 'user_email_footer' => 'Per modificare le impostazioni di notifiche via email per favore accedi a: '.SITE_URL.'/company/notifications', 'invoice_link_message' => 'Per visualizzare la tua fattura del cliente clicca sul link qui sotto:', - 'notification_paid_subject' => 'La fattura :invoice è stata pagata da :client', - 'notification_sent_subject' => 'La fattura :invoice è stata inviata a :client', - 'notification_viewed_subject' => 'La fattura :invoice è stata visualizzata da :client', - 'notification_paid' => 'Un pagamento di :amount è stato effettuato dal cliente :client attraverso la fattura :invoice.', - 'notification_sent' => 'Al seguente cliente :client è stata inviata via email la fattura :invoice di :amount.', - 'notification_viewed' => 'Il seguente cliente :client ha visualizzato la fattura :invoice di :amount.', + 'notification_invoice_paid_subject' => 'La fattura :invoice è stata pagata da :client', + 'notification_invoice_sent_subject' => 'La fattura :invoice è stata inviata a :client', + 'notification_invoice_viewed_subject' => 'La fattura :invoice è stata visualizzata da :client', + 'notification_invoice_paid' => 'Un pagamento di :amount è stato effettuato dal cliente :client attraverso la fattura :invoice.', + 'notification_invoice_sent' => 'Al seguente cliente :client è stata inviata via email la fattura :invoice di :amount.', + 'notification_invoice_viewed' => 'Il seguente cliente :client ha visualizzato la fattura :invoice di :amount.', 'reset_password' => 'Puoi resettare la password del tuo account cliccando sul link qui sotto:', 'reset_password_footer' => 'Se non sei stato tu a voler resettare la password per favore invia un\'email di assistenza a: ' . CONTACT_EMAIL, @@ -337,4 +337,46 @@ return array( 'chart_builder' => 'Chart Builder', 'ninja_email_footer' => 'Use :site to invoice your clients and get paid online for free!', + + // Quotes + 'quote' => 'Quote', + 'quotes' => 'Quotes', + 'quote_number' => 'Quote Number', + 'quote_number_short' => 'Quote #', + 'quote_date' => 'Quote Date', + 'quote_total' => 'Quote Total', + 'your_quote' => 'Your Quote', + 'total' => 'Total', + 'clone' => 'Clone', + + 'new_quote' => 'New Quote', + 'create_quote' => 'Create Quote', + 'edit_quote' => 'Edit Quote', + 'archive_quote' => 'Archive Quote', + 'delete_quote' => 'Delete Quote', + 'save_quote' => 'Save Quote', + 'email_quote' => 'Email Quote', + 'clone_quote' => 'Clone Quote', + 'convert_to_invoice' => 'Convert to Invoice', + 'view_invoice' => 'View Invoice', + 'view_quote' => 'View Quote', + + 'updated_quote' => 'Successfully updated quote', + 'created_quote' => 'Successfully created quote', + 'cloned_quote' => 'Successfully cloned quote', + 'emailed_quote' => 'Successfully emailed quote', + 'archived_quote' => 'Successfully archived quote', + 'archived_quotes' => 'Successfully archived :count quotes', + 'deleted_quote' => 'Successfully deleted quote', + 'deleted_quotes' => 'Successfully deleted :count quotes', + 'converted_to_invoice' => 'Successfully converted quote to invoice', + + 'quote_subject' => 'New quote from :account', + 'quote_message' => 'To view your quote for :amount, click the link below.', + 'quote_link_message' => 'To view your client quote click the link below:', + 'notification_quote_sent_subject' => 'Quote :invoice was sent to :client', + 'notification_quote_viewed_subject' => 'Quote :invoice was viewed by :client', + 'notification_quote_sent' => 'The following client :client was emailed Quote :invoice for :amount.', + 'notification_quote_viewed' => 'The following client :client viewed Quote :invoice for :amount.', + ); diff --git a/app/lang/nl/texts.php b/app/lang/nl/texts.php index fa4deda053..3003eb71e3 100644 --- a/app/lang/nl/texts.php +++ b/app/lang/nl/texts.php @@ -260,12 +260,12 @@ return array( 'email_from' => 'Het InvoiceNinja Team', 'user_email_footer' => 'Ga alstublieft naar '.SITE_URL.'/company/notifications om je e-mail notificatie instellingen aan te passen ', 'invoice_link_message' => 'Klik op volgende link om de Factuur van je klant te bekijken:', - 'notification_paid_subject' => 'Factuur :invoice is betaald door :client', - 'notification_sent_subject' => 'Factuur :invoice is gezonden door :client', - 'notification_viewed_subject' => 'Factuur :invoice is bekeken door :client', - 'notification_paid' => 'Een betaling voor :amount is gemaakt door klant :client voor Factuur :invoice.', - 'notification_sent' => 'De volgende klant :client heeft Factuur :invoice voor :amount gemaild gekregen.', - 'notification_viewed' => 'De volgende klant :client heeft Factuur :invoice voor :amount bekeken.', + 'notification_invoice_paid_subject' => 'Factuur :invoice is betaald door :client', + 'notification_invoice_sent_subject' => 'Factuur :invoice is gezonden door :client', + 'notification_invoice_viewed_subject' => 'Factuur :invoice is bekeken door :client', + 'notification_invoice_paid' => 'Een betaling voor :amount is gemaakt door klant :client voor Factuur :invoice.', + 'notification_invoice_sent' => 'De volgende klant :client heeft Factuur :invoice voor :amount gemaild gekregen.', + 'notification_invoice_viewed' => 'De volgende klant :client heeft Factuur :invoice voor :amount bekeken.', 'reset_password' => 'Je kan het paswoord van je account resetten door op volgende link te klikken:', 'reset_password_footer' => 'Als je deze paswoord reset niet aangevraagd hebt contacteer dan onze helpdesk alstublieft: ' . CONTACT_EMAIL, @@ -337,5 +337,47 @@ return array( 'chart_builder' => 'Chart Builder', 'ninja_email_footer' => 'Use :site to invoice your clients and get paid online for free!', + + + // Quotes + 'quote' => 'Quote', + 'quotes' => 'Quotes', + 'quote_number' => 'Quote Number', + 'quote_number_short' => 'Quote #', + 'quote_date' => 'Quote Date', + 'quote_total' => 'Quote Total', + 'your_quote' => 'Your Quote', + 'total' => 'Total', + 'clone' => 'Clone', + + 'new_quote' => 'New Quote', + 'create_quote' => 'Create Quote', + 'edit_quote' => 'Edit Quote', + 'archive_quote' => 'Archive Quote', + 'delete_quote' => 'Delete Quote', + 'save_quote' => 'Save Quote', + 'email_quote' => 'Email Quote', + 'clone_quote' => 'Clone Quote', + 'convert_to_invoice' => 'Convert to Invoice', + 'view_invoice' => 'View Invoice', + 'view_quote' => 'View Quote', + + 'updated_quote' => 'Successfully updated quote', + 'created_quote' => 'Successfully created quote', + 'cloned_quote' => 'Successfully cloned quote', + 'emailed_quote' => 'Successfully emailed quote', + 'archived_quote' => 'Successfully archived quote', + 'archived_quotes' => 'Successfully archived :count quotes', + 'deleted_quote' => 'Successfully deleted quote', + 'deleted_quotes' => 'Successfully deleted :count quotes', + 'converted_to_invoice' => 'Successfully converted quote to invoice', + + 'quote_subject' => 'New quote from :account', + 'quote_message' => 'To view your quote for :amount, click the link below.', + 'quote_link_message' => 'To view your client quote click the link below:', + 'notification_quote_sent_subject' => 'Quote :invoice was sent to :client', + 'notification_quote_viewed_subject' => 'Quote :invoice was viewed by :client', + 'notification_quote_sent' => 'The following client :client was emailed Quote :invoice for :amount.', + 'notification_quote_viewed' => 'The following client :client viewed Quote :invoice for :amount.', ); diff --git a/app/lang/pt_BR/texts.php b/app/lang/pt_BR/texts.php index c7597a53c2..26f8f5b9a0 100644 --- a/app/lang/pt_BR/texts.php +++ b/app/lang/pt_BR/texts.php @@ -258,12 +258,12 @@ return array( 'email_from' => 'Equipe InvoiceNinja', 'user_email_footer' => 'Para ajustar suas configurações de notificações de email acesse '.SITE_URL.'/company/notifications', 'invoice_link_message' => 'Para visualizar a fatura do seu cliente clique no link abaixo:', - 'notification_paid_subject' => 'Fatura :invoice foi pago por :client', - 'notification_sent_subject' => 'Fatura :invoice foi enviado por :client', - 'notification_viewed_subject' => 'Fatura :invoice foi visualizada por :client', - 'notification_paid' => 'Um pagamento de :amount foi realizado pelo cliente :client através da fatura :invoice.', - 'notification_sent' => 'O cliente :client foi notificado por email referente à fatura :invoice de :amount.', - 'notification_viewed' => 'O cliente :client visualizou a fatura :invoice de :amount.', + 'notification_invoice_paid_subject' => 'Fatura :invoice foi pago por :client', + 'notification_invoice_sent_subject' => 'Fatura :invoice foi enviado por :client', + 'notification_invoice_viewed_subject' => 'Fatura :invoice foi visualizada por :client', + 'notification_invoice_paid' => 'Um pagamento de :amount foi realizado pelo cliente :client através da fatura :invoice.', + 'notification_invoice_sent' => 'O cliente :client foi notificado por email referente à fatura :invoice de :amount.', + 'notification_invoice_viewed' => 'O cliente :client visualizou a fatura :invoice de :amount.', 'reset_password' => 'Você pode redefinir a sua senha clicando no seguinte link:', 'reset_password_footer' => 'Se você não solicitou a redefinição de sua senha por favor envie um email para o nosso suporte: ' . CONTACT_EMAIL, @@ -326,5 +326,47 @@ return array( 'chart_builder' => 'Chart Builder', 'ninja_email_footer' => 'Use :site to invoice your clients and get paid online for free!', + + // Quotes + 'quote' => 'Quote', + 'quotes' => 'Quotes', + 'quote_number' => 'Quote Number', + 'quote_number_short' => 'Quote #', + 'quote_date' => 'Quote Date', + 'quote_total' => 'Quote Total', + 'your_quote' => 'Your Quote', + 'total' => 'Total', + 'clone' => 'Clone', + + 'new_quote' => 'New Quote', + 'create_quote' => 'Create Quote', + 'edit_quote' => 'Edit Quote', + 'archive_quote' => 'Archive Quote', + 'delete_quote' => 'Delete Quote', + 'save_quote' => 'Save Quote', + 'email_quote' => 'Email Quote', + 'clone_quote' => 'Clone Quote', + 'convert_to_invoice' => 'Convert to Invoice', + 'view_invoice' => 'View Invoice', + 'view_quote' => 'View Quote', + + 'updated_quote' => 'Successfully updated quote', + 'created_quote' => 'Successfully created quote', + 'cloned_quote' => 'Successfully cloned quote', + 'emailed_quote' => 'Successfully emailed quote', + 'archived_quote' => 'Successfully archived quote', + 'archived_quotes' => 'Successfully archived :count quotes', + 'deleted_quote' => 'Successfully deleted quote', + 'deleted_quotes' => 'Successfully deleted :count quotes', + 'converted_to_invoice' => 'Successfully converted quote to invoice', + + 'quote_subject' => 'New quote from :account', + 'quote_message' => 'To view your quote for :amount, click the link below.', + 'quote_link_message' => 'To view your client quote click the link below:', + 'notification_quote_sent_subject' => 'Quote :invoice was sent to :client', + 'notification_quote_viewed_subject' => 'Quote :invoice was viewed by :client', + 'notification_quote_sent' => 'The following client :client was emailed Quote :invoice for :amount.', + 'notification_quote_viewed' => 'The following client :client viewed Quote :invoice for :amount.', + ); diff --git a/app/libraries/utils.php b/app/libraries/utils.php index accb7ec6ed..637a5019b5 100755 --- a/app/libraries/utils.php +++ b/app/libraries/utils.php @@ -286,26 +286,29 @@ class Utils $object = new stdClass; $object->url = $url; $object->name = ucwords($type) . ': ' . $name; - + + $data = []; + for ($i=0; $iurl == $item->url) + if ($object->url == $item->url || $object->name == $item->name) { - array_splice($viewed, $i, 1); - break; - } + continue; + } + + array_unshift($data, $item); } - array_unshift($viewed, $object); + array_unshift($data, $object); - if (count($viewed) > RECENTLY_VIEWED_LIMIT) + if (count($data) > RECENTLY_VIEWED_LIMIT) { - array_pop($viewed); + array_pop($data); } - Session::put(RECENTLY_VIEWED, $viewed); + Session::put(RECENTLY_VIEWED, $data); } public static function processVariables($str) diff --git a/app/models/Account.php b/app/models/Account.php index 7058e2a55a..ca8df787b7 100755 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -203,6 +203,11 @@ class Account extends Eloquent 'balance_due', 'terms', 'your_invoice', + 'quote', + 'your_quote', + 'quote_date', + 'quote_number', + 'total' ]; foreach ($fields as $field) diff --git a/app/models/Activity.php b/app/models/Activity.php index e56580a070..69572401a9 100755 --- a/app/models/Activity.php +++ b/app/models/Activity.php @@ -22,6 +22,13 @@ define("ACTIVITY_TYPE_UPDATE_CREDIT", 15); define("ACTIVITY_TYPE_ARCHIVE_CREDIT", 16); define("ACTIVITY_TYPE_DELETE_CREDIT", 17); +define("ACTIVITY_TYPE_CREATE_QUOTE", 18); +define("ACTIVITY_TYPE_UPDATE_QUOTE", 19); +define("ACTIVITY_TYPE_EMAIL_QUOTE", 20); +define("ACTIVITY_TYPE_VIEW_QUOTE", 21); +define("ACTIVITY_TYPE_ARCHIVE_QUOTE", 22); +define("ACTIVITY_TYPE_DELETE_QUOTE", 23); + class Activity extends Eloquent { @@ -105,15 +112,19 @@ class Activity extends Eloquent $message = Utils::encodeActivity(null, 'created', $invoice); } + $adjustment = 0; $client = $invoice->client; - $adjustment = $invoice->amount; - $client->balance = $client->balance + $adjustment; - $client->save(); + if (!$invoice->is_quote) + { + $adjustment = $invoice->amount; + $client->balance = $client->balance + $adjustment; + $client->save(); + } $activity = Activity::getBlank($invoice); $activity->invoice_id = $invoice->id; $activity->client_id = $invoice->client_id; - $activity->activity_type_id = ACTIVITY_TYPE_CREATE_INVOICE; + $activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_CREATE_QUOTE : ACTIVITY_TYPE_CREATE_INVOICE; $activity->message = $message; $activity->balance = $client->balance; $activity->adjustment = $adjustment; @@ -129,18 +140,21 @@ class Activity extends Eloquent if (!$invoice->is_deleted) { - $client = $invoice->client; - $client->balance = $client->balance - $invoice->balance; - $client->paid_to_date = $client->paid_to_date - ($invoice->amount - $invoice->balance); - $client->save(); + if (!$invoice->is_quote) + { + $client = $invoice->client; + $client->balance = $client->balance - $invoice->balance; + $client->paid_to_date = $client->paid_to_date - ($invoice->amount - $invoice->balance); + $client->save(); + } $activity = Activity::getBlank(); $activity->invoice_id = $invoice->id; $activity->client_id = $invoice->client_id; - $activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_INVOICE; + $activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_ARCHIVE_QUOTE : ACTIVITY_TYPE_ARCHIVE_INVOICE; $activity->message = Utils::encodeActivity(Auth::user(), 'archived', $invoice); $activity->balance = $invoice->client->balance; - $activity->adjustment = $invoice->balance; + $activity->adjustment = $invoice->is_quote ? 0 : $invoice->balance; $activity->save(); } @@ -155,7 +169,7 @@ class Activity extends Eloquent $activity->client_id = $invitation->invoice->client_id; $activity->invoice_id = $invitation->invoice_id; $activity->contact_id = $invitation->contact_id; - $activity->activity_type_id = ACTIVITY_TYPE_EMAIL_INVOICE; + $activity->activity_type_id = $invitation->invoice ? ACTIVITY_TYPE_EMAIL_QUOTE : ACTIVITY_TYPE_EMAIL_INVOICE; $activity->message = Utils::encodeActivity(Auth::check() ? Auth::user() : null, 'emailed', $invitation->invoice, $invitation->contact); $activity->balance = $client->balance; $activity->save(); @@ -165,18 +179,21 @@ class Activity extends Eloquent { if ($invoice->is_deleted && !$invoice->getOriginal('is_deleted')) { - $client = $invoice->client; - $client->balance = $client->balance - $invoice->balance; - $client->paid_to_date = $client->paid_to_date - ($invoice->amount - $invoice->balance); - $client->save(); + if (!$invoice->is_quote) + { + $client = $invoice->client; + $client->balance = $client->balance - $invoice->balance; + $client->paid_to_date = $client->paid_to_date - ($invoice->amount - $invoice->balance); + $client->save(); + } $activity = Activity::getBlank(); $activity->client_id = $invoice->client_id; $activity->invoice_id = $invoice->id; - $activity->activity_type_id = ACTIVITY_TYPE_DELETE_INVOICE; + $activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_DELETE_QUOTE : ACTIVITY_TYPE_DELETE_INVOICE; $activity->message = Utils::encodeActivity(Auth::user(), 'deleted', $invoice); $activity->balance = $invoice->client->balance; - $activity->adjustment = $invoice->balance * -1; + $activity->adjustment = $invoice->is_quote ? 0 : $invoice->balance * -1; $activity->save(); } else @@ -197,10 +214,10 @@ class Activity extends Eloquent $activity = Activity::getBlank($invoice); $activity->client_id = $invoice->client_id; $activity->invoice_id = $invoice->id; - $activity->activity_type_id = ACTIVITY_TYPE_UPDATE_INVOICE; + $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 = $diff; + $activity->adjustment = $invoice->is_quote ? 0 : $diff; $activity->json_backup = $backupInvoice->hidePrivateFields()->toJSON(); $activity->save(); } @@ -236,7 +253,7 @@ class Activity extends Eloquent $activity->invitation_id = $invitation->id; $activity->contact_id = $invitation->contact_id; $activity->invoice_id = $invitation->invoice_id; - $activity->activity_type_id = ACTIVITY_TYPE_VIEW_INVOICE; + $activity->activity_type_id = $invitation->invoice->is_quote ? ACTIVITY_TYPE_VIEW_QUOTE : ACTIVITY_TYPE_VIEW_INVOICE; $activity->message = Utils::encodeActivity($invitation->contact, 'viewed', $invitation->invoice); $activity->balance = $invitation->invoice->client->balance; $activity->save(); diff --git a/app/models/Invoice.php b/app/models/Invoice.php index 5b5eea24ca..4195e2cacb 100755 --- a/app/models/Invoice.php +++ b/app/models/Invoice.php @@ -39,7 +39,7 @@ class Invoice extends EntityModel public function getEntityType() { - return ENTITY_INVOICE; + return $this->is_quote ? ENTITY_QUOTE : ENTITY_INVOICE; } public function isSent() @@ -75,7 +75,8 @@ class Invoice extends EntityModel 'tax_rate', 'account', 'invoice_design_id', - 'is_pro']); + 'is_pro', + 'is_quote']); $this->client->setVisible([ 'name', diff --git a/app/ninja/mailers/ContactMailer.php b/app/ninja/mailers/ContactMailer.php index c63b45a7b9..35ae0d6902 100755 --- a/app/ninja/mailers/ContactMailer.php +++ b/app/ninja/mailers/ContactMailer.php @@ -14,9 +14,10 @@ class ContactMailer extends Mailer { public function sendInvoice(Invoice $invoice) { $invoice->load('invitations', 'client', 'account'); + $entityType = $invoice->getEntityType(); $view = 'invoice'; - $subject = trans('texts.invoice_subject', ['invoice' => $invoice->invoice_number, 'account' => $invoice->account->getDisplayName()]); + $subject = trans("texts.{$entityType}_subject", ['invoice' => $invoice->invoice_number, 'account' => $invoice->account->getDisplayName()]); foreach ($invoice->invitations as $invitation) { @@ -29,6 +30,7 @@ class ContactMailer extends Mailer { $invitation->save(); $data = [ + 'entityType' => $entityType, 'link' => $invitation->getLink(), 'clientName' => $invoice->client->getDisplayName(), 'accountName' => $invoice->account->getDisplayName(), diff --git a/app/ninja/mailers/UserMailer.php b/app/ninja/mailers/UserMailer.php index b66d07e3ae..7c10ae9708 100755 --- a/app/ninja/mailers/UserMailer.php +++ b/app/ninja/mailers/UserMailer.php @@ -25,22 +25,24 @@ class UserMailer extends Mailer { $this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); } - public function sendNotification(User $user, Invoice $invoice, $type, Payment $payment = null) + public function sendNotification(User $user, Invoice $invoice, $notificationType, Payment $payment = null) { if (!$user->email) { return; } - $view = 'invoice_' . $type; + $view = 'invoice_' . $notificationType; + $entityType = $invoice->getEntityType(); $data = [ + 'entityType' => $entityType, 'clientName' => $invoice->client->getDisplayName(), 'accountName' => $invoice->account->getDisplayName(), 'userName' => $user->getDisplayName(), 'invoiceAmount' => Utils::formatMoney($invoice->amount, $invoice->client->currency_id), 'invoiceNumber' => $invoice->invoice_number, - 'invoiceLink' => SITE_URL . "/invoices/{$invoice->public_id}" + 'invoiceLink' => SITE_URL . "/{$entityType}s/{$invoice->public_id}" ]; if ($payment) @@ -48,7 +50,7 @@ class UserMailer extends Mailer { $data['paymentAmount'] = Utils::formatMoney($payment->amount, $invoice->client->currency_id); } - $subject = trans('texts.notification_'.$type.'_subject', ['invoice'=>$invoice->invoice_number, 'client'=>$invoice->client->getDisplayName()]); + $subject = trans("texts.notification_{$entityType}_{$notificationType}_subject", ['invoice'=>$invoice->invoice_number, 'client'=>$invoice->client->getDisplayName()]); $this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); } diff --git a/app/ninja/repositories/InvoiceRepository.php b/app/ninja/repositories/InvoiceRepository.php index 5ecf57cea7..9da5d06874 100755 --- a/app/ninja/repositories/InvoiceRepository.php +++ b/app/ninja/repositories/InvoiceRepository.php @@ -2,6 +2,7 @@ use Invoice; use InvoiceItem; +use Invitation; use Product; use Utils; use TaxRate; @@ -14,11 +15,11 @@ class InvoiceRepository ->join('clients', 'clients.id', '=','invoices.client_id') ->join('invoice_statuses', 'invoice_statuses.id', '=', 'invoices.invoice_status_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') - ->where('invoices.account_id', '=', $accountId) - ->where('clients.deleted_at', '=', null) + ->where('invoices.account_id', '=', $accountId) + ->where('clients.deleted_at', '=', null) ->where('invoices.is_recurring', '=', false) ->where('contacts.is_primary', '=', true) - ->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email'); + ->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'quote_id', 'quote_invoice_id'); if (!\Session::get('show_trash')) { @@ -53,6 +54,7 @@ class InvoiceRepository ->join('frequencies', 'frequencies.id', '=', 'invoices.frequency_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') ->where('invoices.account_id', '=', $accountId) + ->where('invoices.is_quote', '=', false) ->where('clients.deleted_at', '=', null) ->where('invoices.is_recurring', '=', true) ->where('contacts.is_primary', '=', true) @@ -82,12 +84,8 @@ class InvoiceRepository public function getDatatable($accountId, $clientPublicId = null, $entityType, $search) { - $query = $this->getInvoices($accountId, $clientPublicId, $search); - - if ($entityType == ENTITY_QUOTE) - { - $query->where('invoices.is_quote', '=', true); - } + $query = $this->getInvoices($accountId, $clientPublicId, $search) + ->where('invoices.is_quote', '=', $entityType == ENTITY_QUOTE ? true : false); $table = \Datatable::query($query); @@ -120,17 +118,26 @@ class InvoiceRepository '.trans('texts.select').'