forked from invoiceninja/invoiceninja
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request invoiceninja#10113 from beganovich/einvoicing-pepp…
…ol-form-api EInvoicing: PEPPOL setup for hosted
- Loading branch information
Showing
11 changed files
with
304 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?php | ||
/** | ||
* Invoice Ninja (https://invoiceninja.com). | ||
* | ||
* @link https://github.com/invoiceninja/invoiceninja source repository | ||
* | ||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com) | ||
* | ||
* @license https://www.elastic.co/licensing/elastic-license | ||
*/ | ||
|
||
namespace App\Http\Controllers; | ||
|
||
use App\Http\Requests\EInvoice\Peppol\CreateRequest; | ||
use App\Http\Requests\EInvoice\Peppol\DisconnectRequest; | ||
use App\Services\EDocument\Gateway\Storecove\Storecove; | ||
use Illuminate\Http\Response; | ||
|
||
class EInvoicePeppolController extends BaseController | ||
{ | ||
public function setup(CreateRequest $request, Storecove $storecove): Response | ||
{ | ||
/** | ||
* @var \App\Models\Company | ||
*/ | ||
$company = auth()->user()->company(); | ||
|
||
$data = [ | ||
...$request->validated(), | ||
'country' => $request->country()->iso_3166_2, | ||
]; | ||
|
||
$legal_entity_response = $storecove->createLegalEntity($data, $company); | ||
|
||
$add_identifier_response = $storecove->addIdentifier( | ||
legal_entity_id: $legal_entity_response['id'], | ||
identifier: $company->settings->vat_number, | ||
scheme: $request->receiverIdentifier(), | ||
); | ||
|
||
if ($add_identifier_response) { | ||
$company->legal_entity_id = $legal_entity_response['id']; | ||
$company->save(); | ||
|
||
return response()->noContent(); | ||
} | ||
|
||
// @todo: Improve with proper error. | ||
|
||
return response()->noContent(status: 422); | ||
} | ||
|
||
public function disconnect(DisconnectRequest $request, Storecove $storecove): Response | ||
{ | ||
/** | ||
* @var \App\Models\Company | ||
*/ | ||
$company = auth()->user()->company(); | ||
|
||
$response = $storecove->deleteIdentifier( | ||
legal_entity_id: $company->legal_entity_id, | ||
); | ||
|
||
if ($response) { | ||
$company->legal_entity_id = null; | ||
$company->save(); | ||
|
||
return response()->noContent(); | ||
|
||
} | ||
|
||
// @todo: Improve with proper error. | ||
|
||
return response()->noContent(status: 422); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?php | ||
|
||
/** | ||
* Invoice Ninja (https://invoiceninja.com). | ||
* | ||
* @link https://github.com/invoiceninja/invoiceninja source repository | ||
* | ||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com) | ||
* | ||
* @license https://www.elastic.co/licensing/elastic-license | ||
*/ | ||
|
||
namespace App\Http\Requests\EInvoice\Peppol; | ||
|
||
use App\Models\Country; | ||
use App\Rules\EInvoice\Peppol\SupportsReceiverIdentifier; | ||
use App\Services\EDocument\Standards\Peppol\ReceiverIdentifier; | ||
use Illuminate\Auth\Access\AuthorizationException; | ||
use Illuminate\Foundation\Http\FormRequest; | ||
|
||
class CreateRequest extends FormRequest | ||
{ | ||
public function authorize(): bool | ||
{ | ||
/** | ||
* @var \App\Models\User | ||
*/ | ||
$user = auth()->user(); | ||
|
||
if (app()->isLocal()) { | ||
return true; | ||
} | ||
|
||
return $user->account->isPaid() && | ||
$user->company()->legal_entity_id === null; | ||
} | ||
|
||
/** | ||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string> | ||
*/ | ||
public function rules(): array | ||
{ | ||
return [ | ||
'party_name' => ['required', 'string'], | ||
'line1' => ['required', 'string'], | ||
'line2' => ['nullable', 'string'], | ||
'city' => ['required', 'string'], | ||
'country' => ['required', 'integer', 'exists:countries,id', new SupportsReceiverIdentifier()], | ||
'zip' => ['required', 'string'], | ||
'county' => ['required', 'string'], | ||
]; | ||
} | ||
|
||
protected function failedAuthorization(): void | ||
{ | ||
throw new AuthorizationException( | ||
message: ctrans('texts.peppol_not_paid_message'), | ||
); | ||
} | ||
|
||
public function country(): Country | ||
{ | ||
return Country::find($this->country); | ||
} | ||
|
||
public function receiverIdentifier(): string | ||
{ | ||
$identifier = new ReceiverIdentifier($this->country()->iso_3166_2); | ||
|
||
return $identifier->get(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
|
||
/** | ||
* Invoice Ninja (https://invoiceninja.com). | ||
* | ||
* @link https://github.com/invoiceninja/invoiceninja source repository | ||
* | ||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com) | ||
* | ||
* @license https://www.elastic.co/licensing/elastic-license | ||
*/ | ||
|
||
namespace App\Http\Requests\EInvoice\Peppol; | ||
|
||
use App\Models\Country; | ||
use App\Rules\EInvoice\Peppol\SupportsReceiverIdentifier; | ||
use App\Services\EDocument\Standards\Peppol\ReceiverIdentifier; | ||
use Illuminate\Auth\Access\AuthorizationException; | ||
use Illuminate\Foundation\Http\FormRequest; | ||
|
||
class DisconnectRequest extends FormRequest | ||
{ | ||
public function authorize(): bool | ||
{ | ||
/** | ||
* @var \App\Models\User | ||
*/ | ||
$user = auth()->user(); | ||
|
||
if (app()->isLocal()) { | ||
return true; | ||
} | ||
|
||
return $user->account->isPaid() && | ||
$user->company()->legal_entity_id !== null; | ||
} | ||
|
||
/** | ||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string> | ||
*/ | ||
public function rules(): array | ||
{ | ||
return []; | ||
} | ||
|
||
protected function failedAuthorization(): void | ||
{ | ||
throw new AuthorizationException( | ||
message: ctrans('texts.peppol_not_paid_message'), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
namespace App\Rules\EInvoice\Peppol; | ||
|
||
use App\Models\Country; | ||
use App\Services\EDocument\Standards\Peppol\ReceiverIdentifier; | ||
use Closure; | ||
use Illuminate\Contracts\Validation\ValidationRule; | ||
|
||
class SupportsReceiverIdentifier implements ValidationRule | ||
{ | ||
/** | ||
* Run the validation rule. | ||
* | ||
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail | ||
*/ | ||
public function validate(string $attribute, mixed $value, Closure $fail): void | ||
{ | ||
$country = Country::find($value); | ||
|
||
if ($country === null) { | ||
$fail(ctrans('texts.peppol_country_not_supported')); | ||
} | ||
|
||
$checker = new ReceiverIdentifier($country->iso_3166_2); | ||
|
||
if ($checker->get() === null) { | ||
$fail(ctrans('texts.peppol_country_not_supported')); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
app/Services/EDocument/Standards/Peppol/ReceiverIdentifier.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
/** | ||
* Invoice Ninja (https://invoiceninja.com). | ||
* | ||
* @link https://github.com/invoiceninja/invoiceninja source repository | ||
* | ||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com) | ||
* | ||
* @license https://www.elastic.co/licensing/elastic-license | ||
*/ | ||
|
||
namespace App\Services\EDocument\Standards\Peppol; | ||
|
||
// https://www.storecove.com/docs/#_receiver_identifiers_list | ||
|
||
class ReceiverIdentifier | ||
{ | ||
public array $mappings = [ | ||
'DE' => 'DE:VAT', | ||
|
||
// @todo: Check with Dave what other countries we support. | ||
]; | ||
|
||
public function __construct( | ||
public string $country, | ||
) { | ||
} | ||
|
||
public function get(): ?string | ||
{ | ||
return $this->mappings[$this->country] ?? null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
database/migrations/2024_10_11_153311_add_e_invoicing_token.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
|
||
return new class extends Migration | ||
{ | ||
public function up(): void | ||
{ | ||
Schema::table('companies', function (Blueprint $table) { | ||
$table->string('e_invoicing_token')->nullable(); | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters