diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index c52d6267aa39..c38aee312a8c 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -21,6 +21,7 @@ use App\Http\Requests\Client\EditClientRequest; use App\Http\Requests\Client\ShowClientRequest; use App\Http\Requests\Client\StoreClientRequest; use App\Http\Requests\Client\UpdateClientRequest; +use App\Http\Requests\Client\UploadClientRequest; use App\Jobs\Client\StoreClient; use App\Jobs\Client\UpdateClient; use App\Models\Client; @@ -29,6 +30,7 @@ use App\Transformers\ClientTransformer; 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; @@ -42,6 +44,7 @@ class ClientController extends BaseController use MakesHash; use Uploadable; use BulkOptions; + use SavesDocuments; protected $entity_type = Client::class; @@ -269,6 +272,7 @@ class ClientController extends BaseController */ public function update(UpdateClientRequest $request, Client $client) { + if ($request->entityIsDeleted($client)) { return $request->disallowUpdate(); } @@ -515,4 +519,66 @@ class ClientController extends BaseController { //todo } + + /** + * Update the specified resource in storage. + * + * @param UploadClientRequest $request + * @param Client $client + * @return Response + * + * + * + * @OA\Put( + * path="/api/v1/clients/{id}/upload", + * operationId="uploadClient", + * tags={"clients"}, + * summary="Uploads a document to a client", + * description="Handles the uploading of a document to a client", + * @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 Client Hashed ID", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the client 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/Client"), + * ), + * @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(UploadClientRequest $request, Client $client) + { + + if ($request->has('documents')) + $this->saveDocuments($request->file('documents'), $client); + + return $this->itemResponse($client->fresh()); + + } + } diff --git a/app/Http/Controllers/CompanyController.php b/app/Http/Controllers/CompanyController.php index 0b437b32b2b7..9bfffe27f6d8 100644 --- a/app/Http/Controllers/CompanyController.php +++ b/app/Http/Controllers/CompanyController.php @@ -20,6 +20,7 @@ use App\Http\Requests\Company\EditCompanyRequest; use App\Http\Requests\Company\ShowCompanyRequest; use App\Http\Requests\Company\StoreCompanyRequest; use App\Http\Requests\Company\UpdateCompanyRequest; +use App\Http\Requests\Company\UploadCompanyRequest; use App\Jobs\Company\CreateCompany; use App\Jobs\Company\CreateCompanyPaymentTerms; use App\Jobs\Company\CreateCompanyTaskStatuses; @@ -503,4 +504,65 @@ class CompanyController extends BaseController return response()->json(['message' => ctrans('texts.success')], 200); } + + /** + * Update the specified resource in storage. + * + * @param UploadCompanyRequest $request + * @param Company $client + * @return Response + * + * + * + * @OA\Put( + * path="/api/v1/companies/{id}/upload", + * operationId="uploadCompanies", + * tags={"companies"}, + * summary="Uploads a document to a company", + * description="Handles the uploading of a document to a company", + * @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 Company Hashed ID", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the client 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/Company"), + * ), + * @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(UploadCompanyRequest $request, Company $company) + { + + if ($request->has('documents')) + $this->saveDocuments($request->file('documents'), $company); + + return $this->itemResponse($company->fresh()); + + } } diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index d287ebb5ede0..d2dae952e74f 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -393,8 +393,6 @@ class InvoiceController extends BaseController $invoice = $this->invoice_repo->save($request->all(), $invoice); - UnlinkFile::dispatchNow(config('filesystems.default'), $invoice->client->invoice_filepath().$invoice->number.'.pdf'); - event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars())); return $this->itemResponse($invoice); diff --git a/app/Http/Requests/Client/UploadClientRequest.php b/app/Http/Requests/Client/UploadClientRequest.php new file mode 100644 index 000000000000..4a7848472547 --- /dev/null +++ b/app/Http/Requests/Client/UploadClientRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->client); + } + + 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/Company/UploadCompanyRequest.php b/app/Http/Requests/Company/UploadCompanyRequest.php new file mode 100644 index 000000000000..7f9079d74799 --- /dev/null +++ b/app/Http/Requests/Company/UploadCompanyRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->company); + } + + public function rules() + { + + $rules = []; + + if($this->input('documents')) + $rules['documents'] = 'file|mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:20000'; + + return $rules; + + } +} diff --git a/app/Jobs/Util/UploadFile.php b/app/Jobs/Util/UploadFile.php index 9930f403bf3b..a33fe8b55964 100644 --- a/app/Jobs/Util/UploadFile.php +++ b/app/Jobs/Util/UploadFile.php @@ -78,7 +78,7 @@ class UploadFile implements ShouldQueue $instance = Storage::disk($this->disk)->putFileAs( $path, $this->file, - $this->file->hashName() + $this->file->hashName() ); if (in_array($this->file->extension(), ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'psd'])) { diff --git a/app/Notifications/Admin/EntitySentNotification.php b/app/Notifications/Admin/EntitySentNotification.php index 0608e3790732..b499d8313699 100644 --- a/app/Notifications/Admin/EntitySentNotification.php +++ b/app/Notifications/Admin/EntitySentNotification.php @@ -88,9 +88,7 @@ class EntitySentNotification extends Notification implements ShouldQueue */ public function toArray($notifiable) { - return [ - // - ]; + return []; } public function toSlack($notifiable) diff --git a/app/Observers/CreditObserver.php b/app/Observers/CreditObserver.php new file mode 100644 index 000000000000..9969f7f02c60 --- /dev/null +++ b/app/Observers/CreditObserver.php @@ -0,0 +1,75 @@ +client->credit_filepath() . $credit->number.'.pdf'); + } + + /** + * Handle the client "deleted" event. + * + * @param Credit $credit + * @return void + */ + public function deleted(Credit $credit) + { + + } + + /** + * Handle the client "restored" event. + * + * @param Credit $credit + * @return void + */ + public function restored(Credit $credit) + { + // + } + + /** + * Handle the client "force deleted" event. + * + * @param Credit $credit + * @return void + */ + public function forceDeleted(Credit $credit) + { + // + } +} diff --git a/app/Observers/InvoiceObserver.php b/app/Observers/InvoiceObserver.php index cee12d293a29..14f5aa9c68de 100644 --- a/app/Observers/InvoiceObserver.php +++ b/app/Observers/InvoiceObserver.php @@ -11,6 +11,7 @@ namespace App\Observers; +use App\Jobs\Util\UnlinkFile; use App\Jobs\Util\WebhookHandler; use App\Models\Client; use App\Models\Invoice; @@ -50,6 +51,9 @@ class InvoiceObserver if ($subscriptions) { WebhookHandler::dispatch(Webhook::EVENT_UPDATE_INVOICE, $invoice, $invoice->company); } + + UnlinkFile::dispatchNow(config('filesystems.default'), $invoice->client->invoice_filepath() . $invoice->number.'.pdf'); + } /** diff --git a/app/Observers/QuoteObserver.php b/app/Observers/QuoteObserver.php index 89ca20f81624..f2a9471111af 100644 --- a/app/Observers/QuoteObserver.php +++ b/app/Observers/QuoteObserver.php @@ -11,6 +11,7 @@ namespace App\Observers; +use App\Jobs\Util\UnlinkFile; use App\Jobs\Util\WebhookHandler; use App\Models\Quote; use App\Models\Webhook; @@ -49,6 +50,9 @@ class QuoteObserver if ($subscriptions) { WebhookHandler::dispatch(Webhook::EVENT_UPDATE_QUOTE, $quote, $quote->company); } + + UnlinkFile::dispatchNow(config('filesystems.default'), $quote->client->quote_filepath() . $quote->number.'.pdf'); + } /** diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 9937060e098a..3d96377fa950 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -16,6 +16,7 @@ use App\Models\Client; use App\Models\Company; use App\Models\CompanyGateway; use App\Models\CompanyToken; +use App\Models\Credit; use App\Models\Expense; use App\Models\Invoice; use App\Models\Payment; @@ -29,6 +30,7 @@ use App\Observers\ClientObserver; use App\Observers\CompanyGatewayObserver; use App\Observers\CompanyObserver; use App\Observers\CompanyTokenObserver; +use App\Observers\CreditObserver; use App\Observers\ExpenseObserver; use App\Observers\InvoiceObserver; use App\Observers\PaymentObserver; @@ -79,6 +81,7 @@ class AppServiceProvider extends ServiceProvider Company::observe(CompanyObserver::class); CompanyGateway::observe(CompanyGatewayObserver::class); CompanyToken::observe(CompanyTokenObserver::class); + Credit::observe(CreditObserver::class); Expense::observe(ExpenseObserver::class); Invoice::observe(InvoiceObserver::class); Payment::observe(PaymentObserver::class); diff --git a/app/Services/Credit/ApplyPayment.php b/app/Services/Credit/ApplyPayment.php index e97e38c3854b..40a6652e1e71 100644 --- a/app/Services/Credit/ApplyPayment.php +++ b/app/Services/Credit/ApplyPayment.php @@ -147,7 +147,7 @@ class ApplyPayment event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars())); if ((int)$this->invoice->balance == 0) { - $this->invoice->service()->deletePdf(); + // $this->invoice->service()->deletePdf(); event(new InvoiceWasPaid($this->invoice, $payment, $this->payment->company, Ninja::eventVars())); } } diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index b45e5eb19b6e..ccaa2e929954 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -266,7 +266,7 @@ class InvoiceService //$this->invoice = $this->invoice->calc()->getInvoice(); - $this->deletePdf(); + // $this->deletePdf(); return $this; } diff --git a/routes/api.php b/routes/api.php index dd5509523ea7..f21f23c56c75 100644 --- a/routes/api.php +++ b/routes/api.php @@ -32,6 +32,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::get('activities/download_entity/{activity}', 'ActivityController@downloadHistoricalEntity'); 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'); @@ -128,6 +129,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a 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');