From e546764e29469264095ffde04dbed8b2ba7c9c12 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 16 Feb 2021 07:58:19 +1100 Subject: [PATCH 1/4] Upload documents route --- .../Controllers/OpenAPI/DocumentSchema.php | 23 +++++++ app/Http/Controllers/PaymentController.php | 64 +++++++++++++++++++ app/Http/Controllers/ProductController.php | 64 +++++++++++++++++++ app/Http/Controllers/ProjectController.php | 62 ++++++++++++++++++ app/Http/Controllers/QuoteController.php | 64 +++++++++++++++++++ .../RecurringInvoiceController.php | 64 +++++++++++++++++++ .../Requests/Payment/UploadPaymentRequest.php | 39 +++++++++++ .../Requests/Product/UploadProductRequest.php | 39 +++++++++++ .../Requests/Project/UploadProjectRequest.php | 39 +++++++++++ .../Requests/Quote/UploadQuoteRequest.php | 39 +++++++++++ .../UploadRecurringInvoiceRequest.php | 39 +++++++++++ 11 files changed, 536 insertions(+) create mode 100644 app/Http/Controllers/OpenAPI/DocumentSchema.php create mode 100644 app/Http/Requests/Payment/UploadPaymentRequest.php create mode 100644 app/Http/Requests/Product/UploadProductRequest.php create mode 100644 app/Http/Requests/Project/UploadProjectRequest.php create mode 100644 app/Http/Requests/Quote/UploadQuoteRequest.php create mode 100644 app/Http/Requests/RecurringInvoice/UploadRecurringInvoiceRequest.php diff --git a/app/Http/Controllers/OpenAPI/DocumentSchema.php b/app/Http/Controllers/OpenAPI/DocumentSchema.php new file mode 100644 index 0000000000..12e0372441 --- /dev/null +++ b/app/Http/Controllers/OpenAPI/DocumentSchema.php @@ -0,0 +1,23 @@ +itemResponse($payment); } + +/** + * Update the specified resource in storage. + * + * @param UploadPaymentRequest $request + * @param Payment $payment + * @return Response + * + * + * + * @OA\Put( + * path="/api/v1/payments/{id}/upload", + * operationId="uploadPayment", + * tags={"payments"}, + * summary="Uploads a document to a payment", + * description="Handles the uploading of a document to a payment", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/include"), + * @OA\Parameter( + * name="id", + * in="path", + * description="The Payment Hashed ID", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the Payment object", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * @OA\JsonContent(ref="#/components/schemas/Payment"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + * + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + */ + public function upload(UploadPaymentRequest $request, Payment $payment) + { + + if ($request->has('documents')) + $this->saveDocuments($request->file('documents'), $payment); + + return $this->itemResponse($payment->fresh()); + + } } diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php index fd0248c248..3ee844e2de 100644 --- a/app/Http/Controllers/ProductController.php +++ b/app/Http/Controllers/ProductController.php @@ -19,16 +19,19 @@ use App\Http\Requests\Product\EditProductRequest; use App\Http\Requests\Product\ShowProductRequest; use App\Http\Requests\Product\StoreProductRequest; use App\Http\Requests\Product\UpdateProductRequest; +use App\Http\Requests\Product\UploadProductRequest; use App\Models\Product; use App\Repositories\ProductRepository; use App\Transformers\ProductTransformer; use App\Utils\Traits\MakesHash; +use App\Utils\Traits\SavesDocuments; use Illuminate\Http\Request; use Illuminate\Http\Response; class ProductController extends BaseController { use MakesHash; + use SavesDocuments; protected $entity_type = Product::class; @@ -476,4 +479,65 @@ class ProductController extends BaseController return $this->listResponse(Product::withTrashed()->whereIn('id', $this->transformKeys($ids))); } + +/** + * Update the specified resource in storage. + * + * @param UploadProductRequest $request + * @param Product $product + * @return Response + * + * + * + * @OA\Put( + * path="/api/v1/products/{id}/upload", + * operationId="uploadProduct", + * tags={"products"}, + * summary="Uploads a document to a product", + * description="Handles the uploading of a document to a product", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/include"), + * @OA\Parameter( + * name="id", + * in="path", + * description="The Product Hashed ID", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the Product object", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * @OA\JsonContent(ref="#/components/schemas/Product"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + * + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + */ + public function upload(UploadProductRequest $request, Product $product) + { + + if ($request->has('documents')) + $this->saveDocuments($request->file('documents'), $product); + + return $this->itemResponse($product->fresh()); + + } } diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 2c8da54d3e..5868f1b337 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -19,6 +19,7 @@ use App\Http\Requests\Project\EditProjectRequest; use App\Http\Requests\Project\ShowProjectRequest; use App\Http\Requests\Project\StoreProjectRequest; use App\Http\Requests\Project\UpdateProjectRequest; +use App\Http\Requests\Project\UploadProjectRequest; use App\Models\Project; use App\Repositories\ProjectRepository; use App\Transformers\ProjectTransformer; @@ -503,4 +504,65 @@ class ProjectController extends BaseController return $this->listResponse(Project::withTrashed()->whereIn('id', $this->transformKeys($ids))); } + + /** + * Update the specified resource in storage. + * + * @param UploadProductRequest $request + * @param Product $project + * @return Response + * + * + * + * @OA\Put( + * path="/api/v1/projects/{id}/upload", + * operationId="uploadProject", + * tags={"projects"}, + * summary="Uploads a document to a project", + * description="Handles the uploading of a document to a project", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/include"), + * @OA\Parameter( + * name="id", + * in="path", + * description="The Project Hashed ID", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the Project object", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * @OA\JsonContent(ref="#/components/schemas/Project"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + * + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + */ + public function upload(UploadProjectRequest $request, Product $project) + { + + if ($request->has('documents')) + $this->saveDocuments($request->file('documents'), $project); + + return $this->itemResponse($project->fresh()); + + } } diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php index d80d5b244c..7f6cc661bc 100644 --- a/app/Http/Controllers/QuoteController.php +++ b/app/Http/Controllers/QuoteController.php @@ -24,6 +24,7 @@ use App\Http\Requests\Quote\EditQuoteRequest; use App\Http\Requests\Quote\ShowQuoteRequest; use App\Http\Requests\Quote\StoreQuoteRequest; use App\Http\Requests\Quote\UpdateQuoteRequest; +use App\Http\Requests\Quote\UploadQuoteRequest; use App\Jobs\Invoice\ZipInvoices; use App\Models\Client; use App\Models\Invoice; @@ -34,6 +35,7 @@ use App\Transformers\QuoteTransformer; use App\Utils\Ninja; use App\Utils\TempFile; use App\Utils\Traits\MakesHash; +use App\Utils\Traits\SavesDocuments; use Illuminate\Http\Request; use Illuminate\Http\Response; @@ -43,6 +45,7 @@ use Illuminate\Http\Response; class QuoteController extends BaseController { use MakesHash; + use SavesDocuments; protected $entity_type = Quote::class; @@ -717,4 +720,65 @@ class QuoteController extends BaseController return response()->download($file_path); } + + /** + * Update the specified resource in storage. + * + * @param UploadQuoteRequest $request + * @param Quote $quote + * @return Response + * + * + * + * @OA\Put( + * path="/api/v1/quotes/{id}/upload", + * operationId="uploadQuote", + * tags={"quotes"}, + * summary="Uploads a document to a quote", + * description="Handles the uploading of a document to a quote", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/include"), + * @OA\Parameter( + * name="id", + * in="path", + * description="The Quote Hashed ID", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the Quote object", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * @OA\JsonContent(ref="#/components/schemas/Quote"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + * + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + */ + public function upload(UploadQuoteRequest $request, Quote $quote) + { + + if ($request->has('documents')) + $this->saveDocuments($request->file('documents'), $quote); + + return $this->itemResponse($quote->fresh()); + + } } diff --git a/app/Http/Controllers/RecurringInvoiceController.php b/app/Http/Controllers/RecurringInvoiceController.php index aae1105220..0a9ce664d4 100644 --- a/app/Http/Controllers/RecurringInvoiceController.php +++ b/app/Http/Controllers/RecurringInvoiceController.php @@ -20,10 +20,12 @@ use App\Http\Requests\RecurringInvoice\EditRecurringInvoiceRequest; use App\Http\Requests\RecurringInvoice\ShowRecurringInvoiceRequest; use App\Http\Requests\RecurringInvoice\StoreRecurringInvoiceRequest; use App\Http\Requests\RecurringInvoice\UpdateRecurringInvoiceRequest; +use App\Http\Requests\RecurringInvoice\UploadRecurringInvoiceRequest; use App\Models\RecurringInvoice; use App\Repositories\RecurringInvoiceRepository; use App\Transformers\RecurringInvoiceTransformer; use App\Utils\Traits\MakesHash; +use App\Utils\Traits\SavesDocuments; use Illuminate\Http\Request; use Illuminate\Http\Response; @@ -33,6 +35,7 @@ use Illuminate\Http\Response; class RecurringInvoiceController extends BaseController { use MakesHash; + use SavesDocuments; protected $entity_type = RecurringInvoice::class; @@ -680,4 +683,65 @@ class RecurringInvoiceController extends BaseController break; } } + +/** + * Update the specified resource in storage. + * + * @param UploadRecurringInvoiceRequest $request + * @param RecurringInvoice $recurring_invoice + * @return Response + * + * + * + * @OA\Put( + * path="/api/v1/recurring_invoices/{id}/upload", + * operationId="uploadRecurringInvoice", + * tags={"recurring_invoices"}, + * summary="Uploads a document to a recurring_invoice", + * description="Handles the uploading of a document to a recurring_invoice", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/include"), + * @OA\Parameter( + * name="id", + * in="path", + * description="The RecurringInvoice Hashed ID", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the RecurringInvoice object", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * @OA\JsonContent(ref="#/components/schemas/RecurringInvoice"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + * + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + */ + public function upload(UploadRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice) + { + + if ($request->has('documents')) + $this->saveDocuments($request->file('documents'), $recurring_invoice); + + return $this->itemResponse($recurring_invoice->fresh()); + + } } diff --git a/app/Http/Requests/Payment/UploadPaymentRequest.php b/app/Http/Requests/Payment/UploadPaymentRequest.php new file mode 100644 index 0000000000..06d8694ef4 --- /dev/null +++ b/app/Http/Requests/Payment/UploadPaymentRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->payment); + } + + public function rules() + { + + $rules = []; + + if($this->input('documents')) + $rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000'; + + return $rules; + + } +} diff --git a/app/Http/Requests/Product/UploadProductRequest.php b/app/Http/Requests/Product/UploadProductRequest.php new file mode 100644 index 0000000000..888c35060b --- /dev/null +++ b/app/Http/Requests/Product/UploadProductRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->product); + } + + public function rules() + { + + $rules = []; + + if($this->input('documents')) + $rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000'; + + return $rules; + + } +} diff --git a/app/Http/Requests/Project/UploadProjectRequest.php b/app/Http/Requests/Project/UploadProjectRequest.php new file mode 100644 index 0000000000..a7a75c16ad --- /dev/null +++ b/app/Http/Requests/Project/UploadProjectRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->project); + } + + public function rules() + { + + $rules = []; + + if($this->input('documents')) + $rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000'; + + return $rules; + + } +} diff --git a/app/Http/Requests/Quote/UploadQuoteRequest.php b/app/Http/Requests/Quote/UploadQuoteRequest.php new file mode 100644 index 0000000000..0f36e2d3bf --- /dev/null +++ b/app/Http/Requests/Quote/UploadQuoteRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->quote); + } + + public function rules() + { + + $rules = []; + + if($this->input('documents')) + $rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000'; + + return $rules; + + } +} diff --git a/app/Http/Requests/RecurringInvoice/UploadRecurringInvoiceRequest.php b/app/Http/Requests/RecurringInvoice/UploadRecurringInvoiceRequest.php new file mode 100644 index 0000000000..3f68950447 --- /dev/null +++ b/app/Http/Requests/RecurringInvoice/UploadRecurringInvoiceRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->recurring_invoice); + } + + public function rules() + { + + $rules = []; + + if($this->input('documents')) + $rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000'; + + return $rules; + + } +} From 6edaf5d55718f8c4848cd7c0203eea8eb3ee58f8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 16 Feb 2021 08:14:30 +1100 Subject: [PATCH 2/4] Entity upload routes + reorder api.php routes file --- app/Http/Controllers/TaskController.php | 64 ++++++ app/Http/Controllers/VendorController.php | 64 ++++++ app/Http/Requests/Task/UploadTaskRequest.php | 39 ++++ .../Requests/Vendor/UploadVendorRequest.php | 39 ++++ routes/api.php | 206 ++++++++---------- 5 files changed, 298 insertions(+), 114 deletions(-) create mode 100644 app/Http/Requests/Task/UploadTaskRequest.php create mode 100644 app/Http/Requests/Vendor/UploadVendorRequest.php diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php index 0b64615be5..d5a3bee52c 100644 --- a/app/Http/Controllers/TaskController.php +++ b/app/Http/Controllers/TaskController.php @@ -21,12 +21,14 @@ use App\Http\Requests\Task\EditTaskRequest; use App\Http\Requests\Task\ShowTaskRequest; use App\Http\Requests\Task\StoreTaskRequest; use App\Http\Requests\Task\UpdateTaskRequest; +use App\Http\Requests\Task\UploadTaskRequest; use App\Models\Task; use App\Repositories\TaskRepository; use App\Transformers\TaskTransformer; use App\Utils\Ninja; use App\Utils\Traits\BulkOptions; use App\Utils\Traits\MakesHash; +use App\Utils\Traits\SavesDocuments; use App\Utils\Traits\Uploadable; use Illuminate\Http\Request; use Illuminate\Http\Response; @@ -40,6 +42,7 @@ class TaskController extends BaseController use MakesHash; use Uploadable; use BulkOptions; + use SavesDocuments; protected $entity_type = Task::class; @@ -506,4 +509,65 @@ class TaskController extends BaseController { //todo } + +/** + * Update the specified resource in storage. + * + * @param UploadTaskRequest $request + * @param Task $task + * @return Response + * + * + * + * @OA\Put( + * path="/api/v1/tasks/{id}/upload", + * operationId="uploadTask", + * tags={"tasks"}, + * summary="Uploads a document to a task", + * description="Handles the uploading of a document to a task", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/include"), + * @OA\Parameter( + * name="id", + * in="path", + * description="The Task Hashed ID", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the Task object", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * @OA\JsonContent(ref="#/components/schemas/Task"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + * + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + */ + public function upload(UploadTaskRequest $request, Task $task) + { + + if ($request->has('documents')) + $this->saveDocuments($request->file('documents'), $task); + + return $this->itemResponse($task->fresh()); + + } } diff --git a/app/Http/Controllers/VendorController.php b/app/Http/Controllers/VendorController.php index f9ce40c6cb..04394ac0c8 100644 --- a/app/Http/Controllers/VendorController.php +++ b/app/Http/Controllers/VendorController.php @@ -21,12 +21,14 @@ use App\Http\Requests\Vendor\EditVendorRequest; use App\Http\Requests\Vendor\ShowVendorRequest; use App\Http\Requests\Vendor\StoreVendorRequest; use App\Http\Requests\Vendor\UpdateVendorRequest; +use App\Http\Requests\Vendor\UploadVendorRequest; use App\Models\Vendor; use App\Repositories\VendorRepository; use App\Transformers\VendorTransformer; use App\Utils\Ninja; use App\Utils\Traits\BulkOptions; use App\Utils\Traits\MakesHash; +use App\Utils\Traits\SavesDocuments; use App\Utils\Traits\Uploadable; use Illuminate\Http\Request; use Illuminate\Http\Response; @@ -39,6 +41,7 @@ class VendorController extends BaseController use MakesHash; use Uploadable; use BulkOptions; + use SavesDocuments; protected $entity_type = Vendor::class; @@ -511,4 +514,65 @@ class VendorController extends BaseController { //todo } + + /** + * Update the specified resource in storage. + * + * @param UploadVendorRequest $request + * @param Vendor $vendor + * @return Response + * + * + * + * @OA\Put( + * path="/api/v1/vendors/{id}/upload", + * operationId="uploadVendor", + * tags={"vendors"}, + * summary="Uploads a document to a vendor", + * description="Handles the uploading of a document to a vendor", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/include"), + * @OA\Parameter( + * name="id", + * in="path", + * description="The Vendor Hashed ID", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the Vendor object", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * @OA\JsonContent(ref="#/components/schemas/Vendor"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + * + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + */ + public function upload(UploadVendorRequest $request, Vendor $vendor) + { + + if ($request->has('documents')) + $this->saveDocuments($request->file('documents'), $vendor); + + return $this->itemResponse($vendor->fresh()); + + } } diff --git a/app/Http/Requests/Task/UploadTaskRequest.php b/app/Http/Requests/Task/UploadTaskRequest.php new file mode 100644 index 0000000000..58b6abd97e --- /dev/null +++ b/app/Http/Requests/Task/UploadTaskRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->task); + } + + public function rules() + { + + $rules = []; + + if($this->input('documents')) + $rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000'; + + return $rules; + + } +} diff --git a/app/Http/Requests/Vendor/UploadVendorRequest.php b/app/Http/Requests/Vendor/UploadVendorRequest.php new file mode 100644 index 0000000000..8aceb379db --- /dev/null +++ b/app/Http/Requests/Vendor/UploadVendorRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->vendor); + } + + public function rules() + { + + $rules = []; + + if($this->input('documents')) + $rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000'; + + return $rules; + + } +} diff --git a/routes/api.php b/routes/api.php index 653244096e..10e5349c3b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -28,94 +28,126 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::get('health_check', 'PingController@health')->name('health_check'); Route::get('activities', 'ActivityController@index'); - Route::get('activities/download_entity/{activity}', 'ActivityController@downloadHistoricalEntity'); + Route::post('claim_license', 'LicenseController@index')->name('license.index'); + Route::resource('clients', 'ClientController'); // name = (clients. index / create / show / update / destroy / edit Route::put('clients/{client}/upload', 'ClientController@upload')->name('clients.upload'); - Route::post('clients/bulk', 'ClientController@bulk')->name('clients.bulk'); - Route::resource('invoices', 'InvoiceController'); // name = (invoices. index / create / show / update / destroy / edit + Route::resource('client_statement', 'ClientStatementController@statement'); // name = (client_statement. index / create / show / update / destroy / edit - Route::get('invoices/{invoice}/delivery_note', 'InvoiceController@deliveryNote')->name('invoices.delivery_note'); + Route::post('companies/purge/{company}', 'MigrationController@purgeCompany')->middleware('password_protected'); + Route::post('companies/purge_save_settings/{company}', 'MigrationController@purgeCompanySaveSettings')->middleware('password_protected'); + Route::resource('companies', 'CompanyController'); // name = (companies. index / create / show / update / destroy / edit + Route::put('companies/{company}/upload', 'CompanyController@upload'); - Route::get('invoices/{invoice}/{action}', 'InvoiceController@action')->name('invoices.action'); - Route::put('invoices/{invoice}/upload', 'InvoiceController@upload')->name('invoices.upload'); + Route::get('company_ledger', 'CompanyLedgerController@index')->name('company_ledger.index'); - Route::get('invoice/{invitation_key}/download', 'InvoiceController@downloadPdf')->name('invoices.downloadPdf'); + Route::resource('company_gateways', 'CompanyGatewayController'); + Route::post('company_gateways/bulk', 'CompanyGatewayController@bulk')->name('company_gateways.bulk'); - Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk'); + Route::put('company_users/{user}', 'CompanyUserController@update'); Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit Route::put('credits/{credit}/upload', 'CreditController@upload')->name('credits.upload'); - Route::get('credits/{credit}/{action}', 'CreditController@action')->name('credits.action'); - Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk'); - Route::resource('products', 'ProductController'); // name = (products. index / create / show / update / destroy / edit + Route::resource('designs', 'DesignController'); // name = (payments. index / create / show / update / destroy / edit + Route::post('designs/bulk', 'DesignController@bulk')->name('designs.bulk'); - Route::post('products/bulk', 'ProductController@bulk')->name('products.bulk'); - - Route::resource('quotes', 'QuoteController'); // name = (quotes. index / create / show / update / destroy / edit - - Route::get('quotes/{quote}/{action}', 'QuoteController@action')->name('quotes.action'); - - Route::post('quotes/bulk', 'QuoteController@bulk')->name('quotes.bulk'); - - Route::resource('recurring_invoices', 'RecurringInvoiceController'); // name = (recurring_invoices. index / create / show / update / destroy / edit - - Route::post('recurring_invoices/bulk', 'RecurringInvoiceController@bulk')->name('recurring_invoices.bulk'); - - Route::resource('recurring_quotes', 'RecurringQuoteController'); // name = (recurring_invoices. index / create / show / update / destroy / edit - - Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk'); - - Route::resource('expenses', 'ExpenseController'); // name = (expenses. index / create / show / update / destroy / edit - Route::put('expenses/{expense}/upload', 'ExpenseController@upload'); - - Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk'); - - Route::resource('expense_categories', 'ExpenseCategoryController'); // name = (expense_categories. index / create / show / update / destroy / edit - - Route::post('expense_categories/bulk', 'ExpenseCategoryController@bulk')->name('expense_categories.bulk'); - - Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit - - Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk'); - - Route::resource('task_statuses', 'TaskStatusController'); // name = (task_statuses. index / create / show / update / destroy / edit - - Route::post('task_statuses/bulk', 'TaskStatusController@bulk')->name('task_statuses.bulk'); - - Route::resource('projects', 'ProjectController'); // name = (projects. index / create / show / update / destroy / edit - Route::post('projects/bulk', 'ProjectController@bulk')->name('projects.bulk'); - - Route::resource('vendors', 'VendorController'); // name = (vendors. index / create / show / update / destroy / edit - - Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk'); Route::resource('documents', 'DocumentController'); // name = (documents. index / create / show / update / destroy / edit Route::get('documents/{document}/download', 'DocumentController@download')->name('documents.download'); Route::post('documents/bulk', 'DocumentController@bulk')->name('documents.bulk'); - Route::resource('client_statement', 'ClientStatementController@statement'); // name = (client_statement. index / create / show / update / destroy / edit + Route::post('emails', 'EmailController@send')->name('email.send'); - Route::resource('payment_terms', 'PaymentTermController'); // name = (payments. index / create / show / update / destroy / edit + Route::resource('expenses', 'ExpenseController'); // name = (expenses. index / create / show / update / destroy / edit + Route::put('expenses/{expense}/upload', 'ExpenseController@upload'); + Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk'); - Route::post('payment_terms/bulk', 'PaymentTermController@bulk')->name('payment_terms.bulk'); + Route::resource('expense_categories', 'ExpenseCategoryController'); // name = (expense_categories. index / create / show / update / destroy / edit + Route::post('expense_categories/bulk', 'ExpenseCategoryController@bulk')->name('expense_categories.bulk'); - Route::resource('payments', 'PaymentController'); // name = (payments. index / create / show / update / destroy / edit + Route::resource('group_settings', 'GroupSettingController'); + Route::post('group_settings/bulk', 'GroupSettingController@bulk'); - Route::post('payments/refund', 'PaymentController@refund')->name('payments.refund'); + Route::post('import', 'ImportController@import')->name('import.import'); + Route::post('preimport', 'ImportController@preimport')->name('import.preimport'); - Route::post('payments/bulk', 'PaymentController@bulk')->name('payments.bulk'); + Route::resource('invoices', 'InvoiceController'); // name = (invoices. index / create / show / update / destroy / edit + Route::get('invoices/{invoice}/delivery_note', 'InvoiceController@deliveryNote')->name('invoices.delivery_note'); + Route::get('invoices/{invoice}/{action}', 'InvoiceController@action')->name('invoices.action'); + Route::put('invoices/{invoice}/upload', 'InvoiceController@upload')->name('invoices.upload'); + Route::get('invoice/{invitation_key}/download', 'InvoiceController@downloadPdf')->name('invoices.downloadPdf'); + Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk'); Route::post('migrate', 'MigrationController@index')->name('migrate.start'); - Route::resource('designs', 'DesignController'); // name = (payments. index / create / show / update / destroy / edit - Route::post('designs/bulk', 'DesignController@bulk')->name('designs.bulk'); + Route::post('migration/purge/{company}', 'MigrationController@purgeCompany')->middleware('password_protected'); + Route::post('migration/purge_save_settings/{company}', 'MigrationController@purgeCompanySaveSettings')->middleware('password_protected'); + Route::post('migration/start', 'MigrationController@startMigration'); + + Route::resource('payments', 'PaymentController'); // name = (payments. index / create / show / update / destroy / edit + Route::post('payments/refund', 'PaymentController@refund')->name('payments.refund'); + Route::post('payments/bulk', 'PaymentController@bulk')->name('payments.bulk'); + Route::put('payments/{payment}/upload', 'PaymentController@upload'); + + Route::resource('payment_terms', 'PaymentTermController'); // name = (payments. index / create / show / update / destroy / edit + Route::post('payment_terms/bulk', 'PaymentTermController@bulk')->name('payment_terms.bulk'); + + Route::post('preview', 'PreviewController@show')->name('preview.show'); + + Route::resource('products', 'ProductController'); // name = (products. index / create / show / update / destroy / edit + Route::post('products/bulk', 'ProductController@bulk')->name('products.bulk'); + Route::put('products/{product}/upload', 'ProductController@upload'); + + Route::resource('projects', 'ProjectController'); // name = (projects. index / create / show / update / destroy / edit + Route::post('projects/bulk', 'ProjectController@bulk')->name('projects.bulk'); + + Route::resource('quotes', 'QuoteController'); // name = (quotes. index / create / show / update / destroy / edit + Route::get('quotes/{quote}/{action}', 'QuoteController@action')->name('quotes.action'); + Route::post('quotes/bulk', 'QuoteController@bulk')->name('quotes.bulk'); + Route::put('quotes/{quote}/upload', 'QuoteController@upload'); + + Route::resource('recurring_invoices', 'RecurringInvoiceController'); // name = (recurring_invoices. index / create / show / update / destroy / edit + Route::post('recurring_invoices/bulk', 'RecurringInvoiceController@bulk')->name('recurring_invoices.bulk'); + Route::put('recurring_invoices/{recurring_invoice}/upload', 'RecurringInvoiceController@upload'); + Route::resource('recurring_quotes', 'RecurringQuoteController'); // name = (recurring_invoices. index / create / show / update / destroy / edit + + Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk'); + + Route::post('refresh', 'Auth\LoginController@refresh'); + + Route::get('scheduler', 'SchedulerController@index'); + Route::post('support/messages/send', 'Support\Messages\SendingController'); + + Route::post('self-update', 'SelfUpdateController@update')->middleware('password_protected'); + Route::post('self-update/check_version', 'SelfUpdateController@checkVersion'); + + Route::resource('system_logs', 'SystemLogController'); + + Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit + Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk'); + Route::put('tasks/{task}/upload', 'TaskController@upload'); + + Route::resource('task_statuses', 'TaskStatusController'); // name = (task_statuses. index / create / show / update / destroy / edit + Route::post('task_statuses/bulk', 'TaskStatusController@bulk')->name('task_statuses.bulk'); + + Route::resource('tax_rates', 'TaxRateController'); // name = (tax_rates. index / create / show / update / destroy / edit + Route::post('tax_rates/bulk', 'TaxRateController@bulk')->name('tax_rates.bulk'); + + Route::post('templates', 'TemplateController@show')->name('templates.show'); + + Route::resource('tokens', 'TokenController')->middleware('password_protected'); // name = (tokens. index / create / show / update / destroy / edit + Route::post('tokens/bulk', 'TokenController@bulk')->name('tokens.bulk')->middleware('password_protected'); + + Route::resource('vendors', 'VendorController'); // name = (vendors. index / create / show / update / destroy / edit + Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk'); + Route::put('vendors/{vendor}/upload', 'VendorController@upload'); Route::get('users', 'UserController@index'); Route::put('users/{user}', 'UserController@update')->middleware('password_protected'); @@ -124,68 +156,14 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::delete('users/{user}/detach_from_company', 'UserController@detach')->middleware('password_protected'); Route::post('users/bulk', 'UserController@bulk')->name('users.bulk')->middleware('password_protected'); - Route::post('migration/purge/{company}', 'MigrationController@purgeCompany')->middleware('password_protected'); - Route::post('migration/purge_save_settings/{company}', 'MigrationController@purgeCompanySaveSettings')->middleware('password_protected'); - Route::post('companies/purge/{company}', 'MigrationController@purgeCompany')->middleware('password_protected'); - Route::post('companies/purge_save_settings/{company}', 'MigrationController@purgeCompanySaveSettings')->middleware('password_protected'); - - Route::post('migration/start', 'MigrationController@startMigration'); - - Route::resource('companies', 'CompanyController'); // name = (companies. index / create / show / update / destroy / edit - Route::put('companies/{company}/upload', 'CompanyController@upload'); - - Route::resource('tokens', 'TokenController')->middleware('password_protected'); // name = (tokens. index / create / show / update / destroy / edit - Route::post('tokens/bulk', 'TokenController@bulk')->name('tokens.bulk')->middleware('password_protected'); - - Route::resource('company_gateways', 'CompanyGatewayController'); - - Route::post('company_gateways/bulk', 'CompanyGatewayController@bulk')->name('company_gateways.bulk'); - - Route::put('company_users/{user}', 'CompanyUserController@update'); - - Route::resource('group_settings', 'GroupSettingController'); - Route::post('group_settings/bulk', 'GroupSettingController@bulk'); - - Route::resource('tax_rates', 'TaxRateController'); // name = (tax_rates. index / create / show / update / destroy / edit - Route::post('tax_rates/bulk', 'TaxRateController@bulk')->name('tax_rates.bulk'); - - Route::post('refresh', 'Auth\LoginController@refresh'); - - Route::post('templates', 'TemplateController@show')->name('templates.show'); - - Route::post('preview', 'PreviewController@show')->name('preview.show'); - - Route::post('self-update', 'SelfUpdateController@update')->middleware('password_protected'); - - Route::post('self-update/check_version', 'SelfUpdateController@checkVersion'); - - Route::post('claim_license', 'LicenseController@index')->name('license.index'); - - Route::post('emails', 'EmailController@send')->name('email.send'); + Route::resource('webhooks', 'WebhookController'); + Route::post('webhooks/bulk', 'WebhookController@bulk')->name('webhooks.bulk'); /*Subscription and Webhook routes */ // Route::post('hooks', 'SubscriptionController@subscribe')->name('hooks.subscribe'); // Route::delete('hooks/{subscription_id}', 'SubscriptionController@unsubscribe')->name('hooks.unsubscribe'); - Route::resource('webhooks', 'WebhookController'); - Route::resource('system_logs', 'SystemLogController'); - Route::post('webhooks/bulk', 'WebhookController@bulk')->name('webhooks.bulk'); - - /*Company Ledger */ - Route::get('company_ledger', 'CompanyLedgerController@index')->name('company_ledger.index'); - - Route::post('preimport', 'ImportController@preimport')->name('import.preimport'); - Route::post('import', 'ImportController@import')->name('import.import'); - - /* - Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit - - Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk'); - - */ - Route::get('scheduler', 'SchedulerController@index'); - Route::post('support/messages/send', 'Support\Messages\SendingController'); }); Route::match(['get', 'post'], 'payment_webhook/{company_key}/{company_gateway_id}', 'PaymentWebhookController') From 181902fecebef648e448068a7d1c1e7def1e7e56 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 16 Feb 2021 08:52:38 +1100 Subject: [PATCH 3/4] Additional company table properties --- app/Models/Company.php | 2 ++ app/Transformers/CompanyTransformer.php | 2 ++ config/ninja.php | 1 + ...5_214724_additional_company_properties.php | 31 +++++++++++++++++++ 4 files changed, 36 insertions(+) create mode 100644 database/migrations/2021_02_15_214724_additional_company_properties.php diff --git a/app/Models/Company.php b/app/Models/Company.php index e02d87f0b0..97f376d231 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -83,6 +83,8 @@ class Company extends BaseModel 'default_task_is_date_based', 'enable_product_discount', 'expense_inclusive_taxes', + 'session_timeout', + 'oauth_password_required', ]; protected $hidden = [ diff --git a/app/Transformers/CompanyTransformer.php b/app/Transformers/CompanyTransformer.php index b0ea39bb57..3f9b34104f 100644 --- a/app/Transformers/CompanyTransformer.php +++ b/app/Transformers/CompanyTransformer.php @@ -152,6 +152,8 @@ class CompanyTransformer extends EntityTransformer 'hide_empty_columns_on_pdf' => false, // @deprecate 1-2-2021 'expense_inclusive_taxes' => (bool)$company->expense_inclusive_taxes, 'expense_amount_is_pretax' =>(bool)true, //@deprecate 1-2-2021 + 'oauth_password_required' => (bool)$company->oauth_password_required, + 'session_timeout' => (int)$company->session_timeout, ]; } diff --git a/config/ninja.php b/config/ninja.php index 257b18b6be..e9d3de5f95 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -140,4 +140,5 @@ return [ 'expanded_logging' => env('EXPANDED_LOGGING', false), 'snappdf_chromium_path' => env('SNAPPDF_CHROMIUM_PATH', false), 'v4_migration_version' => '4.5.31', + 'flutter_canvas_kit' => env('FLUTTER_CANVAS_KIT', false), ]; diff --git a/database/migrations/2021_02_15_214724_additional_company_properties.php b/database/migrations/2021_02_15_214724_additional_company_properties.php new file mode 100644 index 0000000000..2c76e3be11 --- /dev/null +++ b/database/migrations/2021_02_15_214724_additional_company_properties.php @@ -0,0 +1,31 @@ +integer('session_timeout')->default(0); + $table->boolean('oauth_password_required')->default(0); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} From 4612379811608752ffb3573dff8e27ada21698fe Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 16 Feb 2021 20:02:33 +1100 Subject: [PATCH 4/4] Fixes for file upload on dedicated routes --- app/Http/Controllers/ProjectController.php | 2 +- app/Models/Project.php | 4 ++++ app/Models/Vendor.php | 5 +++++ routes/api.php | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 5868f1b337..ce13b57c94 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -556,7 +556,7 @@ class ProjectController extends BaseController * ), * ) */ - public function upload(UploadProjectRequest $request, Product $project) + public function upload(UploadProjectRequest $request, Project $project) { if ($request->has('documents')) diff --git a/app/Models/Project.php b/app/Models/Project.php index 7d19ca7f90..3e69a6a602 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -67,6 +67,10 @@ class Project extends BaseModel return $this->morphMany(Document::class, 'documentable'); } + public function user() + { + return $this->belongsTo(User::class)->withTrashed(); + } // /** // * @return \Illuminate\Database\Eloquent\Relations\HasMany // */ diff --git a/app/Models/Vendor.php b/app/Models/Vendor.php index d4987f0c18..7373cc5817 100644 --- a/app/Models/Vendor.php +++ b/app/Models/Vendor.php @@ -99,4 +99,9 @@ class Vendor extends BaseModel { return $this->belongsTo(Company::class); } + + public function user() + { + return $this->belongsTo(User::class)->withTrashed(); + } } diff --git a/routes/api.php b/routes/api.php index 10e5349c3b..4b196cb2cf 100644 --- a/routes/api.php +++ b/routes/api.php @@ -107,6 +107,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::resource('projects', 'ProjectController'); // name = (projects. index / create / show / update / destroy / edit Route::post('projects/bulk', 'ProjectController@bulk')->name('projects.bulk'); + Route::put('projects/{project}/upload', 'ProjectController@upload')->name('projects.upload'); Route::resource('quotes', 'QuoteController'); // name = (quotes. index / create / show / update / destroy / edit Route::get('quotes/{quote}/{action}', 'QuoteController@action')->name('quotes.action');