From 113cb6747c0195dd9e2340e87b19128dde070830 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 12 Nov 2014 23:09:42 +0200 Subject: [PATCH] Created quotes, invoices and payments pages for clients --- Gruntfile.js | 2 + app/controllers/InvoiceController.php | 40 +- app/controllers/PaymentController.php | 34 ++ app/controllers/QuoteController.php | 30 + app/ninja/repositories/InvoiceRepository.php | 30 +- app/routes.php | 7 + app/views/header.blade.php | 53 +- app/views/invoices/deleted.blade.php | 8 +- app/views/invoices/view.blade.php | 4 +- app/views/master.blade.php | 38 +- app/views/public/header.blade.php | 20 +- app/views/public_list.blade.php | 133 +++++ public/built.js | 11 - public/built.public.css | 582 ++++++++++++++++++- public/css/splash.css | 4 +- public/js/script.js | 11 - 16 files changed, 911 insertions(+), 96 deletions(-) create mode 100755 app/views/public_list.blade.php diff --git a/Gruntfile.js b/Gruntfile.js index abb85f97b752..efd085d8104a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -96,6 +96,8 @@ module.exports = function(grunt) { 'public/vendor/bootstrap/dist/css/bootstrap.min.css', 'public/css/bootstrap.splash.css', 'public/css/splash.css', + 'public/vendor/datatables/media/css/jquery.dataTables.css', + 'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css', ], dest: 'public/built.public.css', nonull: true diff --git a/app/controllers/InvoiceController.php b/app/controllers/InvoiceController.php index 4827800594d0..0d3742e1a833 100755 --- a/app/controllers/InvoiceController.php +++ b/app/controllers/InvoiceController.php @@ -39,6 +39,18 @@ class InvoiceController extends \BaseController { return View::make('list', $data); } + public function clientIndex() + { + $data = [ + 'showClientHeader' => true, + 'title' => trans('texts.invoices'), + 'entityType'=>ENTITY_INVOICE, + 'columns'=>Utils::trans(['invoice_number', 'invoice_date', 'invoice_total', 'balance_due', 'due_date']) + ]; + + return View::make('public_list', $data); + } + public function getDatatable($clientPublicId = null) { $accountId = Auth::user()->account_id; @@ -47,6 +59,23 @@ class InvoiceController extends \BaseController { return $this->invoiceRepo->getDatatable($accountId, $clientPublicId, ENTITY_INVOICE, $search); } + public function getClientDatatable() + { + //$accountId = Auth::user()->account_id; + $search = Input::get('sSearch'); + $invitationKey = Session::get('invitation_key'); + $invitation = Invitation::where('invitation_key', '=', $invitationKey)->firstOrFail(); + + $invoice = $invitation->invoice; + + if (!$invoice || $invoice->is_deleted) + { + return []; + } + + return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_INVOICE, $search); + } + public function getRecurringDatatable($clientPublicId = null) { $query = $this->invoiceRepo->getRecurringInvoices(Auth::user()->account_id, $clientPublicId, Input::get('sSearch')); @@ -85,7 +114,7 @@ class InvoiceController extends \BaseController { public function view($invitationKey) { - $invitation = Invitation::withTrashed()->where('invitation_key', '=', $invitationKey)->firstOrFail(); + $invitation = Invitation::where('invitation_key', '=', $invitationKey)->firstOrFail(); $invoice = $invitation->invoice; @@ -113,12 +142,15 @@ class InvoiceController extends \BaseController { return View::make('invoices.deleted'); } - if (!Auth::check() || Auth::user()->account_id != $invoice->account_id) + if (!Session::has($invitationKey) && (!Auth::check() || Auth::user()->account_id != $invoice->account_id)) { Activity::viewInvoice($invitation); - Event::fire('invoice.viewed', $invoice); + Event::fire('invoice.viewed', $invoice); } + Session::set($invitationKey, true); + Session::set('invitation_key', $invitationKey); + $client->account->loadLocalizationSettings(); $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); @@ -126,7 +158,7 @@ class InvoiceController extends \BaseController { $invoice->is_pro = $client->account->isPro(); $data = array( - 'hideHeader' => true, + 'showClientHeader' => true, 'showBreadcrumbs' => false, 'invoice' => $invoice->hidePrivateFields(), 'invitation' => $invitation, diff --git a/app/controllers/PaymentController.php b/app/controllers/PaymentController.php index 1e0e9f734c33..c59aa61d79b6 100755 --- a/app/controllers/PaymentController.php +++ b/app/controllers/PaymentController.php @@ -28,6 +28,16 @@ class PaymentController extends \BaseController )); } + public function clientIndex() + { + return View::make('public_list', array( + 'showClientHeader' => true, + 'entityType'=>ENTITY_PAYMENT, + 'title' => trans('texts.payments'), + 'columns'=>Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date']) + )); + } + public function getDatatable($clientPublicId = null) { $payments = $this->paymentRepo->find($clientPublicId, Input::get('sSearch')); @@ -63,6 +73,30 @@ class PaymentController extends \BaseController ->make(); } + public function getClientDatatable() + { + $search = Input::get('sSearch'); + $invitationKey = Session::get('invitation_key'); + $invitation = Invitation::where('invitation_key', '=', $invitationKey)->with('contact.client')->firstOrFail(); + + $invoice = $invitation->invoice; + + if (!$invoice || $invoice->is_deleted) + { + return []; + } + + $payments = $this->paymentRepo->find($invitation->contact->client->public_id, Input::get('sSearch')); + + return Datatable::query($payments) + ->addColumn('invoice_number', function($model) { return $model->invoice_number; }) + ->addColumn('transaction_reference', function($model) { return $model->transaction_reference ? $model->transaction_reference : 'Manual entry'; }) + ->addColumn('payment_type', function($model) { return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? 'Online payment' : ''); }) + ->addColumn('amount', function($model) { return Utils::formatMoney($model->amount, $model->currency_id); }) + ->addColumn('payment_date', function($model) { return Utils::dateToString($model->payment_date); }) + ->make(); + } + public function create($clientPublicId = 0, $invoicePublicId = 0) { diff --git a/app/controllers/QuoteController.php b/app/controllers/QuoteController.php index e0d887c25bd4..66e8d1f1830e 100644 --- a/app/controllers/QuoteController.php +++ b/app/controllers/QuoteController.php @@ -46,6 +46,20 @@ class QuoteController extends \BaseController { return View::make('list', $data); } + + public function clientIndex() + { + $data = [ + 'showClientHeader' => true, + 'title' => trans('texts.quotes'), + 'entityType'=>ENTITY_QUOTE, + 'columns'=>Utils::trans(['quote_number', 'quote_date', 'quote_total', 'due_date']) + ]; + + return View::make('public_list', $data); + } + + public function getDatatable($clientPublicId = null) { $accountId = Auth::user()->account_id; @@ -54,6 +68,22 @@ class QuoteController extends \BaseController { return $this->invoiceRepo->getDatatable($accountId, $clientPublicId, ENTITY_QUOTE, $search); } + public function getClientDatatable() + { + $search = Input::get('sSearch'); + $invitationKey = Session::get('invitation_key'); + $invitation = Invitation::where('invitation_key', '=', $invitationKey)->firstOrFail(); + + $invoice = $invitation->invoice; + + if (!$invoice || $invoice->is_deleted) + { + return []; + } + + return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_QUOTE, $search); + } + public function create($clientPublicId = 0) { if (!Utils::isPro()) diff --git a/app/ninja/repositories/InvoiceRepository.php b/app/ninja/repositories/InvoiceRepository.php index 52d10c7be494..5439e9534f73 100755 --- a/app/ninja/repositories/InvoiceRepository.php +++ b/app/ninja/repositories/InvoiceRepository.php @@ -83,6 +83,35 @@ class InvoiceRepository return $query; } + public function getClientDatatable($contactId, $entityType, $search) + { + $query = \DB::table('invitations') + ->join('invoices', 'invoices.id', '=','invitations.invoice_id') + ->join('clients', 'clients.id', '=','invoices.client_id') + //->join('contacts', 'contacts.client_id', '=', 'clients.id') + ->where('invitations.contact_id', '=', $contactId) + ->where('invitations.deleted_at', '=', null) + ->where('invoices.is_quote', '=', $entityType == ENTITY_QUOTE) + ->where('invoices.is_deleted', '=', false) + ->where('clients.deleted_at', '=', null) + ->where('invoices.is_recurring', '=', false) + ->select('invitation_key', 'invoice_number', 'invoice_date', 'invoices.balance as balance', 'due_date', 'clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'start_date', 'end_date', 'clients.currency_id'); + + $table = \Datatable::query($query) + ->addColumn('invoice_number', function($model) use ($entityType) { return link_to('/view/' . $model->invitation_key, $model->invoice_number); }) + ->addColumn('invoice_date', function($model) { return Utils::fromSqlDate($model->invoice_date); }) + ->addColumn('amount', function($model) { return Utils::formatMoney($model->amount, $model->currency_id); }); + + if ($entityType == ENTITY_INVOICE) + { + $table->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->currency_id); }); + } + + return $table->addColumn('due_date', function($model) { return Utils::fromSqlDate($model->due_date); }) + //->addColumn('invoice_status_name', function($model) { return $model->invoice_status_name; }) + ->make(); + } + public function getDatatable($accountId, $clientPublicId = null, $entityType, $search) { $query = $this->getInvoices($accountId, $clientPublicId, $entityType, $search) @@ -157,7 +186,6 @@ class InvoiceRepository ->make(); } - public function getErrors($input) { $contact = (array) $input->client->contacts[0]; diff --git a/app/routes.php b/app/routes.php index 0c8af89f4c9f..ad470fd641d9 100755 --- a/app/routes.php +++ b/app/routes.php @@ -42,10 +42,17 @@ Route::get('log_error', 'HomeController@logError'); Route::get('invoice_now', 'HomeController@invoiceNow'); Route::post('get_started', 'AccountController@getStarted'); +// Client visible pages Route::get('view/{invitation_key}', 'InvoiceController@view'); Route::get('payment/{invitation_key}', 'PaymentController@show_payment'); Route::post('payment/{invitation_key}', 'PaymentController@do_payment'); Route::get('complete', 'PaymentController@offsite_payment'); +Route::get('client/quotes', 'QuoteController@clientIndex'); +Route::get('client/invoices', 'InvoiceController@clientIndex'); +Route::get('client/payments', 'PaymentController@clientIndex'); +Route::get('api/client.quotes', array('as'=>'api.client.quotes', 'uses'=>'QuoteController@getClientDatatable')); +Route::get('api/client.invoices', array('as'=>'api.client.invoices', 'uses'=>'InvoiceController@getClientDatatable')); +Route::get('api/client.payments', array('as'=>'api.client.payments', 'uses'=>'PaymentController@getClientDatatable')); Route::get('license', 'PaymentController@show_license_payment'); Route::post('license', 'PaymentController@do_license_payment'); diff --git a/app/views/header.blade.php b/app/views/header.blade.php index a6473f6f0243..b1609d603592 100755 --- a/app/views/header.blade.php +++ b/app/views/header.blade.php @@ -3,41 +3,26 @@ @section('head') - + - - -@include('script') - - + + + @include('script') + @stop @section('body') @@ -317,18 +302,6 @@ Want something changed? We're {{ link_to('https://github.com/hillelcoren/invoice
- - -
diff --git a/app/views/invoices/deleted.blade.php b/app/views/invoices/deleted.blade.php index 626de7704096..89a7659ea1a1 100755 --- a/app/views/invoices/deleted.blade.php +++ b/app/views/invoices/deleted.blade.php @@ -1,7 +1 @@ -@extends('header') - -@section('content') - -The requested invoice is no longer available. - -@stop \ No newline at end of file +The requested invoice is no longer available. \ No newline at end of file diff --git a/app/views/invoices/view.blade.php b/app/views/invoices/view.blade.php index 9c8d1b69f580..14db0eebe303 100755 --- a/app/views/invoices/view.blade.php +++ b/app/views/invoices/view.blade.php @@ -5,7 +5,7 @@ @include('script') - + @@ -30,7 +30,7 @@
@else
- {{ Button::primary('Download PDF', array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }} + {{ Button::success('Download PDF', array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}
@endif diff --git a/app/views/master.blade.php b/app/views/master.blade.php index 10afac959e24..ca92bcfde0e2 100755 --- a/app/views/master.blade.php +++ b/app/views/master.blade.php @@ -29,19 +29,31 @@ diff --git a/app/views/public/header.blade.php b/app/views/public/header.blade.php index 50a8d8905b49..abdf58d0289b 100644 --- a/app/views/public/header.blade.php +++ b/app/views/public/header.blade.php @@ -83,7 +83,7 @@ return false; } -@if (!isset($hideHeader) || !$hideHeader) +@if ((!isset($hideHeader) || !$hideHeader) && (!isset($showClientHeader) || !$showClientHeader))