diff --git a/app/Http/Controllers/CompanyController.php b/app/Http/Controllers/CompanyController.php index f6668b6048f9..2ccf9a6012b7 100644 --- a/app/Http/Controllers/CompanyController.php +++ b/app/Http/Controllers/CompanyController.php @@ -409,7 +409,7 @@ class CompanyController extends BaseController public function update(UpdateCompanyRequest $request, Company $company) { - if($request->hasFile('company_logo') || !array_key_exists('company_logo', $request->input('settings'))) + if($request->hasFile('company_logo') || (is_array($request->input('settings')) && !array_key_exists('company_logo', $request->input('settings')))) $this->removeLogo($company); $company = $this->company_repo->save($request->all(), $company); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index dcde8118055d..bcd61c1439c3 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -790,4 +790,57 @@ class InvoiceController extends BaseController return response()->download($file_path, basename($file_path)); } + + /** + * @OA\Get( + * path="/api/v1/invoices/{id}/delivery_note", + * operationId="deliveryNote", + * tags={"invoices"}, + * summary="Download a specific invoice delivery notes", + * description="Downloads a specific invoice delivery notes", + * @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 Invoice Hahsed Id", + * example="D2J234DFA", + * required=true, + * @OA\Schema( + * type="string", + * format="string", + * ), + * ), + * @OA\Response( + * response=200, + * description="Returns the invoice delivery note pdf", + * @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\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"), + * ), + * ) + * @param $invoice + * @return \Symfony\Component\HttpFoundation\BinaryFileResponse + */ + public function deliveryNote(ShowInvoiceRequest $request, Invoice $invoice) + { + + $file_path = $invoice->service()->getInvoiceDeliveryNote($invoice->invitations->first()->contact); + + return response()->download($file_path, basename($file_path)); + + } } diff --git a/app/Http/Controllers/OpenAPI/swagger-v3.php b/app/Http/Controllers/OpenAPI/swagger-v3.php index 310fa73d90bf..3fa768a4a02d 100644 --- a/app/Http/Controllers/OpenAPI/swagger-v3.php +++ b/app/Http/Controllers/OpenAPI/swagger-v3.php @@ -12,15 +12,15 @@ * @OA\License( * name="Attribution Assurance License", * url="https://opensource.org/licenses/AAL" - * ) + * ), * ), * @OA\Server( * description="Example InvoiceNinja base url", - * url="https://ninja.test" + * url="https://ninja.test", * ), * @OA\ExternalDocumentation( * description="http://docs.invoiceninja.com", * url="http://docs.invoiceninja.com" - * ) - * ) + * ), + * ), */ diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 0a17c929ea44..02cfef63b8e5 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -143,6 +143,11 @@ class InvoiceService return (new GetInvoicePdf($this->invoice, $contact))->run(); } + public function getInvoiceDeliveryNote($contact = null) + { + //stubbed + } + public function sendEmail($contact = null) { $send_email = new SendEmail($this->invoice, null, $contact); diff --git a/config/l5-swagger.php b/config/l5-swagger.php new file mode 100644 index 000000000000..b97581cdb9dd --- /dev/null +++ b/config/l5-swagger.php @@ -0,0 +1,198 @@ + 'default', + 'documentations' => [ + 'default' => [ + 'api' => [ + 'title' => 'L5 Swagger UI', + ], + + 'routes' => [ + /* + * Route for accessing api documentation interface + */ + 'api' => 'api/documentation', + ], + 'paths' => [ + /* + * File name of the generated json documentation file + */ + 'docs_json' => 'api-docs.json', + + /* + * File name of the generated YAML documentation file + */ + 'docs_yaml' => 'api-docs.yaml', + + /* + * Absolute paths to directory containing the swagger annotations are stored. + */ + 'annotations' => [ + base_path('app'), + ], + + ], + ], + ], + 'defaults' => [ + 'routes' => [ + /* + * Route for accessing parsed swagger annotations. + */ + 'docs' => 'docs', + + /* + * Route for Oauth2 authentication callback. + */ + 'oauth2_callback' => 'api/oauth2-callback', + + /* + * Middleware allows to prevent unexpected access to API documentation + */ + 'middleware' => [ + 'api' => [], + 'asset' => [], + 'docs' => [], + 'oauth2_callback' => [], + ], + + /* + * Route Group options + */ + 'group_options' => [], + ], + + 'paths' => [ + /* + * Absolute path to location where parsed annotations will be stored + */ + 'docs' => storage_path('api-docs'), + + /* + * Absolute path to directory where to export views + */ + 'views' => base_path('resources/views/vendor/l5-swagger'), + + /* + * Edit to set the api's base path + */ + 'base' => env('L5_SWAGGER_BASE_PATH', null), + + /* + * Edit to set path where swagger ui assets should be stored + */ + 'swagger_ui_assets_path' => env('L5_SWAGGER_UI_ASSETS_PATH', 'vendor/swagger-api/swagger-ui/dist/'), + + /* + * Absolute path to directories that should be exclude from scanning + */ + 'excludes' => [], + ], + + /* + * API security definitions. Will be generated into documentation file. + */ + 'securityDefinitions' => [ + 'securitySchemes' => [ + /* + * Examples of Security schemes + */ + /* + 'api_key_security_example' => [ // Unique name of security + 'type' => 'apiKey', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2". + 'description' => 'A short description for security scheme', + 'name' => 'api_key', // The name of the header or query parameter to be used. + 'in' => 'header', // The location of the API key. Valid values are "query" or "header". + ], + 'oauth2_security_example' => [ // Unique name of security + 'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2". + 'description' => 'A short description for oauth2 security scheme.', + 'flow' => 'implicit', // The flow used by the OAuth2 security scheme. Valid values are "implicit", "password", "application" or "accessCode". + 'authorizationUrl' => 'http://example.com/auth', // The authorization URL to be used for (implicit/accessCode) + //'tokenUrl' => 'http://example.com/auth' // The authorization URL to be used for (password/application/accessCode) + 'scopes' => [ + 'read:projects' => 'read your projects', + 'write:projects' => 'modify projects in your account', + ] + ], + */ + + /* Open API 3.0 support + 'passport' => [ // Unique name of security + 'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2". + 'description' => 'Laravel passport oauth2 security.', + 'in' => 'header', + 'scheme' => 'https', + 'flows' => [ + "password" => [ + "authorizationUrl" => config('app.url') . '/oauth/authorize', + "tokenUrl" => config('app.url') . '/oauth/token', + "refreshUrl" => config('app.url') . '/token/refresh', + "scopes" => [] + ], + ], + ], + */ + ], + 'security' => [ + /* + * Examples of Securities + */ + [ + /* + 'oauth2_security_example' => [ + 'read', + 'write' + ], + + 'passport' => [] + */ + ], + ], + ], + + /* + * Set this to `true` in development mode so that docs would be regenerated on each request + * Set this to `false` to disable swagger generation on production + */ + 'generate_always' => env('L5_SWAGGER_GENERATE_ALWAYS', false), + + /* + * Set this to `true` to generate a copy of documentation in yaml format + */ + 'generate_yaml_copy' => env('L5_SWAGGER_GENERATE_YAML_COPY', false), + + /* + * Edit to trust the proxy's ip address - needed for AWS Load Balancer + * string[] + */ + 'proxy' => false, + + /* + * Configs plugin allows to fetch external configs instead of passing them to SwaggerUIBundle. + * See more at: https://github.com/swagger-api/swagger-ui#configs-plugin + */ + 'additional_config_url' => null, + + /* + * Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), + * 'method' (sort by HTTP method). + * Default is the order returned by the server unchanged. + */ + 'operations_sort' => env('L5_SWAGGER_OPERATIONS_SORT', null), + + /* + * Pass the validatorUrl parameter to SwaggerUi init on the JS side. + * A null value here disables validation. + */ + 'validator_url' => null, + + /* + * Uncomment to add constants which can be used in annotations + */ + // 'constants' => [ + // 'L5_SWAGGER_CONST_HOST' => env('L5_SWAGGER_CONST_HOST', 'http://my-default-host.com'), + // ], + ], +]; diff --git a/resources/views/vendor/l5-swagger/.gitkeep b/resources/views/vendor/l5-swagger/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/resources/views/vendor/l5-swagger/index.blade.php b/resources/views/vendor/l5-swagger/index.blade.php new file mode 100644 index 000000000000..c35050391d72 --- /dev/null +++ b/resources/views/vendor/l5-swagger/index.blade.php @@ -0,0 +1,106 @@ + + + +
+ +