diff --git a/app/Http/Controllers/DocumentController.php b/app/Http/Controllers/DocumentController.php index 0720e1a5babf..d597ba004474 100644 --- a/app/Http/Controllers/DocumentController.php +++ b/app/Http/Controllers/DocumentController.php @@ -12,6 +12,9 @@ use Response; use App\Models\Document; use App\Ninja\Repositories\DocumentRepository; +use App\Http\Requests\DocumentRequest; +use App\Http\Requests\CreateDocumentRequest; + class DocumentController extends BaseController { protected $documentRepo; @@ -24,14 +27,9 @@ class DocumentController extends BaseController $this->documentRepo = $documentRepo; } - public function get($publicId) + public function get(DocumentRequest $request) { - $document = Document::scope($publicId) - ->firstOrFail(); - - $this->authorize('view', $document); - - return static::getDownloadResponse($document); + return static::getDownloadResponse($request->entity()); } public static function getDownloadResponse($document){ @@ -60,12 +58,9 @@ class DocumentController extends BaseController return $response; } - public function getPreview($publicId) + public function getPreview(DocumentRequest $request) { - $document = Document::scope($publicId) - ->firstOrFail(); - - $this->authorize('view', $document); + $document = $request->entity(); if(empty($document->preview)){ return Response::view('error', array('error'=>'Preview does not exist!'), 404); @@ -83,16 +78,14 @@ class DocumentController extends BaseController return $response; } - public function getVFSJS($publicId, $name){ - $document = Document::scope($publicId) - ->firstOrFail(); + public function getVFSJS(DocumentRequest $request, $publicId, $name) + { + $document = $request->entity(); if(substr($name, -3)=='.js'){ $name = substr($name, 0, -3); } - $this->authorize('view', $document); - if(!$document->isPDFEmbeddable()){ return Response::view('error', array('error'=>'Image does not exist!'), 404); } @@ -106,14 +99,12 @@ class DocumentController extends BaseController return $response; } - public function postUpload() + public function postUpload(CreateDocumentRequest $request) { if (!Utils::hasFeature(FEATURE_DOCUMENTS)) { return; } - $this->authorizeCreate(); - $result = $this->documentRepo->upload(Input::all()['file'], $doc_array); if(is_string($result)){ diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php index 53d2a2548e39..fab8aa3bfd3f 100644 --- a/app/Http/Controllers/InvoiceApiController.php +++ b/app/Http/Controllers/InvoiceApiController.php @@ -18,8 +18,8 @@ use App\Ninja\Repositories\InvoiceRepository; use App\Ninja\Mailers\ContactMailer as Mailer; use App\Http\Controllers\BaseAPIController; use App\Ninja\Transformers\InvoiceTransformer; -use App\Http\Requests\CreateInvoiceRequest; -use App\Http\Requests\UpdateInvoiceRequest; +use App\Http\Requests\CreateInvoiceAPIRequest; +use App\Http\Requests\UpdateInvoiceAPIRequest; use App\Services\InvoiceService; class InvoiceApiController extends BaseAPIController @@ -139,7 +139,7 @@ class InvoiceApiController extends BaseAPIController * ) * ) */ - public function store(CreateInvoiceRequest $request) + public function store(CreateInvoiceAPIRequest $request) { $data = Input::all(); $error = null; @@ -351,7 +351,7 @@ class InvoiceApiController extends BaseAPIController * ) * ) */ - public function update(UpdateInvoiceRequest $request, $publicId) + public function update(UpdateInvoiceAPIRequest $request, $publicId) { if ($request->action == ACTION_ARCHIVE) { $invoice = Invoice::scope($publicId)->firstOrFail(); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index c3627a01c301..4dc60f8c7421 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -27,7 +27,10 @@ use App\Ninja\Repositories\ClientRepository; use App\Ninja\Repositories\DocumentRepository; use App\Services\InvoiceService; use App\Services\RecurringInvoiceService; -use App\Http\Requests\SaveInvoiceWithClientRequest; + +use App\Http\Requests\InvoiceRequest; +use App\Http\Requests\CreateInvoiceRequest; +use App\Http\Requests\UpdateInvoiceRequest; class InvoiceController extends BaseController { @@ -88,18 +91,13 @@ class InvoiceController extends BaseController return $this->recurringInvoiceService->getDatatable($accountId, $clientPublicId, ENTITY_RECURRING_INVOICE, $search); } - public function edit($publicId, $clone = false) + public function edit(InvoiceRequest $request, $publicId, $clone = false) { $account = Auth::user()->account; - $invoice = Invoice::scope($publicId) - ->with('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items', 'documents', 'expenses', 'expenses.documents', 'payments') - ->withTrashed() - ->firstOrFail(); - - $this->authorize('edit', $invoice); + $invoice = $request->entity()->load('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items', 'documents', 'expenses', 'expenses.documents', 'payments'); $entityType = $invoice->getEntityType(); - + $contactIds = DB::table('invitations') ->join('contacts', 'contacts.id', '=', 'invitations.contact_id') ->where('invitations.invoice_id', '=', $invoice->id) @@ -120,7 +118,7 @@ class InvoiceController extends BaseController } else { Utils::trackViewed($invoice->getDisplayName().' - '.$invoice->client->getDisplayName(), $invoice->getEntityType()); $method = 'PUT'; - $url = "{$entityType}s/{$publicId}"; + $url = "{$entityType}s/{$invoice->public_id}"; $clients->whereId($invoice->client_id); } @@ -229,28 +227,27 @@ class InvoiceController extends BaseController return View::make('invoices.edit', $data); } - public function create($clientPublicId = 0, $isRecurring = false) + public function create(InvoiceRequest $request, $clientPublicId = 0, $isRecurring = false) { - $this->authorizeCreate(); - $account = Auth::user()->account; + $entityType = $isRecurring ? ENTITY_RECURRING_INVOICE : ENTITY_INVOICE; $clientId = null; - if ($clientPublicId) { - $clientId = Client::getPrivateId($clientPublicId); + if ($request->client_id) { + $clientId = Client::getPrivateId($request->client_id); } $invoice = $account->createInvoice($entityType, $clientId); $invoice->public_id = 0; - if(Session::get('expenses')){ + if (Session::get('expenses')) { $invoice->expenses = Expense::scope(Session::get('expenses'))->with('documents')->get(); } $clients = Client::scope()->with('contacts', 'country')->orderBy('name'); - if(!Auth::user()->hasPermission('view_all')){ + if (!Auth::user()->hasPermission('view_all')) { $clients = $clients->where('clients.user_id', '=', Auth::user()->id); } @@ -267,9 +264,9 @@ class InvoiceController extends BaseController return View::make('invoices.edit', $data); } - public function createRecurring($clientPublicId = 0) + public function createRecurring(ClientRequest $request, $clientPublicId = 0) { - return self::create($clientPublicId, true); + return self::create($request, $clientPublicId, true); } private static function getViewModel($invoice) @@ -395,7 +392,7 @@ class InvoiceController extends BaseController * * @return Response */ - public function store(SaveInvoiceWithClientRequest $request) + public function store(CreateInvoiceRequest $request) { $data = $request->input(); $data['documents'] = $request->file('documents'); @@ -434,7 +431,7 @@ class InvoiceController extends BaseController * @param int $id * @return Response */ - public function update(SaveInvoiceWithClientRequest $request) + public function update(UpdateInvoiceRequest $request) { $data = $request->input(); $data['documents'] = $request->file('documents'); @@ -521,7 +518,7 @@ class InvoiceController extends BaseController { Session::reflash(); - return Redirect::to("invoices/{$publicId}/edit"); + return Redirect::to("invoices/$publicId/edit"); } /** @@ -558,9 +555,9 @@ class InvoiceController extends BaseController return Redirect::to('invoices/'.$clone->public_id); } - public function cloneInvoice($publicId) + public function cloneInvoice(InvoiceRequest $request, $publicId) { - return self::edit($publicId, true); + return self::edit($request, $publicId, true); } public function invoiceHistory($publicId) diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php index 3a0062296098..a8ea0beaa476 100644 --- a/app/Http/Controllers/QuoteController.php +++ b/app/Http/Controllers/QuoteController.php @@ -26,6 +26,7 @@ use App\Ninja\Repositories\InvoiceRepository; use App\Ninja\Repositories\ClientRepository; use App\Events\QuoteInvitationWasApproved; use App\Services\InvoiceService; +use App\Http\Requests\InvoiceRequest; class QuoteController extends BaseController { @@ -78,10 +79,8 @@ class QuoteController extends BaseController return $this->invoiceService->getDatatable($accountId, $clientPublicId, ENTITY_QUOTE, $search); } - public function create($clientPublicId = 0) + public function create(InvoiceRequest $request, $clientPublicId = 0) { - $this->authorizeCreate(); - if (!Utils::hasFeature(FEATURE_QUOTES)) { return Redirect::to('/invoices/create'); } diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php index e78462cd51ac..229a4751116e 100644 --- a/app/Http/Controllers/TaskController.php +++ b/app/Http/Controllers/TaskController.php @@ -75,11 +75,11 @@ class TaskController extends BaseController return $this->save(); } - public function show(TaskRequest $request) + public function show($publicId) { Session::reflash(); - return Redirect::to("tasks/{$request->task_id}/edit"); + return Redirect::to("tasks/{$publicId}/edit"); } /** diff --git a/app/Http/Requests/CreateDocumentRequest.php b/app/Http/Requests/CreateDocumentRequest.php new file mode 100644 index 000000000000..33330a90895e --- /dev/null +++ b/app/Http/Requests/CreateDocumentRequest.php @@ -0,0 +1,26 @@ +user()->can('create', ENTITY_DOCUMENT); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + + ]; + } +} diff --git a/app/Http/Requests/CreateInvoiceAPIRequest.php b/app/Http/Requests/CreateInvoiceAPIRequest.php new file mode 100644 index 000000000000..141d8788abc3 --- /dev/null +++ b/app/Http/Requests/CreateInvoiceAPIRequest.php @@ -0,0 +1,32 @@ +user()->can('create', ENTITY_INVOICE); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + $rules = [ + 'email' => 'required_without:client_id', + 'client_id' => 'required_without:email', + 'invoice_items' => 'valid_invoice_items', + 'invoice_number' => 'unique:invoices,invoice_number,,id,account_id,' . $this->user()->account_id, + 'discount' => 'positive', + ]; + + return $rules; + } +} diff --git a/app/Http/Requests/CreateInvoiceRequest.php b/app/Http/Requests/CreateInvoiceRequest.php index 8531a4074879..a3f556d408e9 100644 --- a/app/Http/Requests/CreateInvoiceRequest.php +++ b/app/Http/Requests/CreateInvoiceRequest.php @@ -1,11 +1,6 @@ user()->can('create', ENTITY_INVOICE); } /** @@ -25,13 +20,18 @@ class CreateInvoiceRequest extends Request public function rules() { $rules = [ - 'email' => 'required_without:client_id', - 'client_id' => 'required_without:email', + 'client.contacts' => 'valid_contacts', 'invoice_items' => 'valid_invoice_items', - 'invoice_number' => 'unique:invoices,invoice_number,,id,account_id,'.Auth::user()->account_id, + 'invoice_number' => 'required|unique:invoices,invoice_number,,id,account_id,' . $this->user()->account_id, 'discount' => 'positive', ]; + /* There's a problem parsing the dates + if (Request::get('is_recurring') && Request::get('start_date') && Request::get('end_date')) { + $rules['end_date'] = 'after' . Request::get('start_date'); + } + */ + return $rules; } } diff --git a/app/Http/Requests/DocumentRequest.php b/app/Http/Requests/DocumentRequest.php new file mode 100644 index 000000000000..a9d4396bc569 --- /dev/null +++ b/app/Http/Requests/DocumentRequest.php @@ -0,0 +1,7 @@ +entityType); - $this->entity = $class::scope($publicId)->withTrashed()->firstOrFail(); + + if (method_exists($class, 'withTrashed')) { + $this->entity = $class::scope($publicId)->withTrashed()->firstOrFail(); + } else { + $this->entity = $class::scope($publicId)->firstOrFail(); + } return $this->entity; } diff --git a/app/Http/Requests/InvoiceRequest.php b/app/Http/Requests/InvoiceRequest.php new file mode 100644 index 000000000000..8e3591d88de7 --- /dev/null +++ b/app/Http/Requests/InvoiceRequest.php @@ -0,0 +1,20 @@ +documents)) { + $expense->load('documents'); + } + + return $expense; + } + */ +} \ No newline at end of file diff --git a/app/Http/Requests/SaveInvoiceWithClientRequest.php b/app/Http/Requests/SaveInvoiceWithClientRequest.php deleted file mode 100644 index a75aee39c8c3..000000000000 --- a/app/Http/Requests/SaveInvoiceWithClientRequest.php +++ /dev/null @@ -1,45 +0,0 @@ - 'valid_contacts', - 'invoice_items' => 'valid_invoice_items', - 'invoice_number' => 'required|unique:invoices,invoice_number,'.$invoiceId.',id,account_id,'.Auth::user()->account_id, - 'discount' => 'positive', - ]; - - /* There's a problem parsing the dates - if (Request::get('is_recurring') && Request::get('start_date') && Request::get('end_date')) { - $rules['end_date'] = 'after' . Request::get('start_date'); - } - */ - - return $rules; - } -} diff --git a/app/Http/Requests/UpdateInvoiceAPIRequest.php b/app/Http/Requests/UpdateInvoiceAPIRequest.php new file mode 100644 index 000000000000..6fa3c4e92e45 --- /dev/null +++ b/app/Http/Requests/UpdateInvoiceAPIRequest.php @@ -0,0 +1,36 @@ +user()->can('edit', $this->entity()); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + if ($this->action == ACTION_ARCHIVE) { + return []; + } + + $invoiceId = $this->entity()->id; + + $rules = [ + 'invoice_items' => 'valid_invoice_items', + 'invoice_number' => 'unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . $this->user()->account_id, + 'discount' => 'positive', + ]; + + return $rules; + } +} diff --git a/app/Http/Requests/UpdateInvoiceRequest.php b/app/Http/Requests/UpdateInvoiceRequest.php index 7827e2b1d1e1..96d112b157c2 100644 --- a/app/Http/Requests/UpdateInvoiceRequest.php +++ b/app/Http/Requests/UpdateInvoiceRequest.php @@ -1,11 +1,6 @@ user()->can('edit', $this->entity()); } /** @@ -24,19 +19,21 @@ class UpdateInvoiceRequest extends Request */ public function rules() { - if ($this->action == ACTION_ARCHIVE) { - return []; - } - - $publicId = $this->route('invoices'); - $invoiceId = Invoice::getPrivateId($publicId); - + $invoiceId = $this->entity()->id; + $rules = [ + 'client.contacts' => 'valid_contacts', 'invoice_items' => 'valid_invoice_items', - 'invoice_number' => 'unique:invoices,invoice_number,'.$invoiceId.',id,account_id,'.Auth::user()->account_id, + 'invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . $this->user()->account_id, 'discount' => 'positive', ]; + /* There's a problem parsing the dates + if (Request::get('is_recurring') && Request::get('start_date') && Request::get('end_date')) { + $rules['end_date'] = 'after' . Request::get('start_date'); + } + */ + return $rules; } } diff --git a/app/Http/routes.php b/app/Http/routes.php index 702cd1fcb98f..768c9c3d3d4c 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -48,8 +48,8 @@ Route::group(['middleware' => 'auth:client'], function() { Route::get('client/documents', 'PublicClientController@documentIndex'); Route::get('client/payments', 'PublicClientController@paymentIndex'); Route::get('client/dashboard', 'PublicClientController@dashboard'); - Route::get('client/document/js/{public_id}/{filename}', 'PublicClientController@getDocumentVFSJS'); - Route::get('client/document/{invitation_key}/{public_id}/{filename?}', 'PublicClientController@getDocument'); + Route::get('client/documents/js/{documents}/{filename}', 'PublicClientController@getDocumentVFSJS'); + Route::get('client/documents/{invitation_key}/{documents}/{filename?}', 'PublicClientController@getDocument'); Route::get('client/documents/{invitation_key}/{filename?}', 'PublicClientController@getInvoiceDocumentsZip'); Route::get('api/client.quotes', array('as'=>'api.client.quotes', 'uses'=>'PublicClientController@quoteDatatable')); @@ -134,20 +134,20 @@ Route::group(['middleware' => 'auth:user'], function() { Route::get('invoices/create/{client_id?}', 'InvoiceController@create'); Route::get('recurring_invoices/create/{client_id?}', 'InvoiceController@createRecurring'); Route::get('recurring_invoices', 'RecurringInvoiceController@index'); - Route::get('invoices/{public_id}/clone', 'InvoiceController@cloneInvoice'); + Route::get('invoices/{invoices}/clone', 'InvoiceController@cloneInvoice'); Route::post('invoices/bulk', 'InvoiceController@bulk'); Route::post('recurring_invoices/bulk', 'InvoiceController@bulk'); - Route::get('document/{public_id}/{filename?}', 'DocumentController@get'); - Route::get('document/js/{public_id}/{filename}', 'DocumentController@getVFSJS'); - Route::get('document/preview/{public_id}/{filename?}', 'DocumentController@getPreview'); + Route::get('documents/{documents}/{filename?}', 'DocumentController@get'); + Route::get('documents/js/{documents}/{filename}', 'DocumentController@getVFSJS'); + Route::get('documents/preview/{documents}/{filename?}', 'DocumentController@getPreview'); Route::post('document', 'DocumentController@postUpload'); Route::get('quotes/create/{client_id?}', 'QuoteController@create'); - Route::get('quotes/{public_id}/clone', 'InvoiceController@cloneInvoice'); - Route::get('quotes/{public_id}/edit', 'InvoiceController@edit'); - Route::put('quotes/{public_id}', 'InvoiceController@update'); - Route::get('quotes/{public_id}', 'InvoiceController@edit'); + Route::get('quotes/{invoices}/clone', 'InvoiceController@cloneInvoice'); + Route::get('quotes/{invoices}/edit', 'InvoiceController@edit'); + Route::put('quotes/{invoices}', 'InvoiceController@update'); + Route::get('quotes/{invoices}', 'InvoiceController@edit'); Route::post('quotes', 'InvoiceController@store'); Route::get('quotes', 'QuoteController@index'); Route::get('api/quotes/{client_id?}', array('as'=>'api.quotes', 'uses'=>'QuoteController@getDatatable')); diff --git a/app/Models/Document.php b/app/Models/Document.php index 0d7fc049aac8..6d9c24857143 100644 --- a/app/Models/Document.php +++ b/app/Models/Document.php @@ -173,11 +173,11 @@ class Document extends EntityModel } public function getUrl(){ - return url('document/'.$this->public_id.'/'.$this->name); + return url('documents/'.$this->public_id.'/'.$this->name); } public function getClientUrl($invitation){ - return url('client/document/'.$invitation->invitation_key.'/'.$this->public_id.'/'.$this->name); + return url('client/documents/'.$invitation->invitation_key.'/'.$this->public_id.'/'.$this->name); } public function isPDFEmbeddable(){ @@ -186,16 +186,16 @@ class Document extends EntityModel public function getVFSJSUrl(){ if(!$this->isPDFEmbeddable())return null; - return url('document/js/'.$this->public_id.'/'.$this->name.'.js'); + return url('documents/js/'.$this->public_id.'/'.$this->name.'.js'); } public function getClientVFSJSUrl(){ if(!$this->isPDFEmbeddable())return null; - return url('client/document/js/'.$this->public_id.'/'.$this->name.'.js'); + return url('client/documents/js/'.$this->public_id.'/'.$this->name.'.js'); } public function getPreviewUrl(){ - return $this->preview?url('document/preview/'.$this->public_id.'/'.$this->name.'.'.pathinfo($this->preview, PATHINFO_EXTENSION)):null; + return $this->preview?url('documents/preview/'.$this->public_id.'/'.$this->name.'.'.pathinfo($this->preview, PATHINFO_EXTENSION)):null; } public function toArray() diff --git a/app/Ninja/Repositories/DocumentRepository.php b/app/Ninja/Repositories/DocumentRepository.php index f33837051e97..094b4848ebe0 100644 --- a/app/Ninja/Repositories/DocumentRepository.php +++ b/app/Ninja/Repositories/DocumentRepository.php @@ -211,7 +211,7 @@ class DocumentRepository extends BaseRepository }) ->addColumn('name', function ($model) { return link_to( - '/client/document/'.$model->invitation_key.'/'.$model->public_id.'/'.$model->name, + '/client/documents/'.$model->invitation_key.'/'.$model->public_id.'/'.$model->name, $model->name, ['target'=>'_blank'] )->toHtml();