1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-15 15:42:51 +01:00
invoiceninja/app/Services/EDocument/Gateway/Storecove/Storecove.php

424 lines
11 KiB
PHP
Raw Normal View History

2024-07-15 06:27:12 +02:00
<?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
*/
2024-07-16 08:49:18 +02:00
namespace App\Services\EDocument\Gateway\Storecove;
2024-07-15 06:27:12 +02:00
2024-08-28 03:12:47 +02:00
use App\DataMapper\Analytics\LegalEntityCreated;
2024-07-16 04:47:42 +02:00
use App\Models\Company;
2024-07-15 06:27:12 +02:00
use Illuminate\Support\Facades\Http;
2024-08-27 06:47:18 +02:00
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use Illuminate\Http\Client\RequestException;
2024-08-28 03:12:47 +02:00
use Turbo124\Beacon\Facades\LightLogs;
2024-07-15 06:27:12 +02:00
enum HttpVerb: string
{
case POST = 'post';
case PUT = 'put';
case GET = 'get';
case PATCH = 'patch';
case DELETE = 'delete';
}
2024-08-22 08:45:06 +02:00
class Storecove
2024-08-27 06:47:18 +02:00
{
2024-08-29 07:25:20 +02:00
/** @var string $base_url */
2024-07-16 08:49:18 +02:00
private string $base_url = 'https://api.storecove.com/api/v2/';
2024-08-27 06:47:18 +02:00
2024-08-29 07:25:20 +02:00
/** @var array $peppol_discovery */
2024-07-15 06:27:12 +02:00
private array $peppol_discovery = [
"documentTypes" => ["invoice"],
"network" => "peppol",
"metaScheme" => "iso6523-actorid-upis",
"scheme" => "de:lwid",
"identifier" => "DE:VAT"
2024-07-15 06:27:12 +02:00
];
2024-08-27 06:47:18 +02:00
2024-08-29 07:25:20 +02:00
/** @var array $dbn_discovery */
2024-07-15 06:27:12 +02:00
private array $dbn_discovery = [
"documentTypes" => ["invoice"],
"network" => "dbnalliance",
"metaScheme" => "iso6523-actorid-upis",
"scheme" => "gln",
"identifier" => "1200109963131"
];
2024-10-10 18:29:43 +02:00
private ?int $legal_entity_id = null;
2024-08-28 02:48:08 +02:00
public StorecoveRouter $router;
2024-09-16 05:12:46 +02:00
public Mutator $mutator;
2024-08-22 08:45:06 +02:00
public function __construct()
{
2024-08-28 02:48:08 +02:00
$this->router = new StorecoveRouter();
2024-09-16 05:12:46 +02:00
$this->mutator = new Mutator($this);
2024-08-22 08:45:06 +02:00
}
2024-08-27 06:47:18 +02:00
/**
* Discovery
*
* @param string $identifier
* @param string $scheme
* @param string $network
* @return bool
*/
public function discovery(string $identifier, string $scheme, string $network = 'peppol'): bool
2024-07-15 06:27:12 +02:00
{
$network_data = [];
match ($network) {
'peppol' => $network_data = array_merge($this->peppol_discovery, ['scheme' => $scheme, 'identifier' => $identifier]),
'dbn' => $network_data = array_merge($this->dbn_discovery, ['scheme' => $scheme, 'identifier' => $identifier]),
default => $network_data = array_merge($this->peppol_discovery, ['scheme' => $scheme, 'identifier' => $identifier]),
};
2024-07-16 04:47:42 +02:00
$uri = "api/v2/discovery/receives";
2024-07-15 06:27:12 +02:00
$r = $this->httpClient($uri, (HttpVerb::POST)->value, $network_data, $this->getHeaders());
return ($r->successful() && $r->json()['code'] == 'OK') ? true : false;
2024-08-22 08:45:06 +02:00
2024-07-15 06:27:12 +02:00
}
2024-08-27 06:47:18 +02:00
2024-07-15 09:09:58 +02:00
/**
2024-08-27 06:47:18 +02:00
* Unused as yet
2024-07-15 09:09:58 +02:00
*
2024-08-27 06:47:18 +02:00
* @param mixed $document
2024-08-29 07:25:20 +02:00
* @return string|bool
2024-07-15 09:09:58 +02:00
*/
2024-08-01 08:32:35 +02:00
public function sendJsonDocument($document)
{
$payload = [
2024-08-27 06:47:18 +02:00
// "legalEntityId" => 290868,
2024-08-01 08:32:35 +02:00
"idempotencyGuid" => \Illuminate\Support\Str::uuid(),
"routing" => [
"eIdentifiers" => [],
"emails" => ["david@invoiceninja.com"]
],
2024-08-22 08:45:06 +02:00
"document" => [
2024-08-01 08:32:35 +02:00
"documentType" => "invoice",
"invoice" => $document,
],
];
2024-08-22 08:45:06 +02:00
2024-08-01 08:32:35 +02:00
$uri = "document_submissions";
$r = $this->httpClient($uri, (HttpVerb::POST)->value, $payload, $this->getHeaders());
if($r->successful()) {
return $r->json()['guid'];
}
return false;
}
2024-08-27 06:47:18 +02:00
/**
* Send Document via StoreCove
*
* @param string $document
* @param int $routing_id
* @param array $override_payload
*
2024-08-29 07:25:20 +02:00
* @return string|\Illuminate\Http\Client\Response
2024-08-27 06:47:18 +02:00
*/
2024-08-29 07:25:20 +02:00
public function sendDocument(string $document, int $routing_id, array $override_payload = [])
2024-07-15 09:09:58 +02:00
{
$this->legal_entity_id = $routing_id;
2024-07-16 00:31:56 +02:00
$payload = [
2024-08-07 04:12:16 +02:00
"legalEntityId" => $routing_id,
2024-08-22 08:45:06 +02:00
"idempotencyGuid" => \Illuminate\Support\Str::uuid(),
2024-07-18 00:53:19 +02:00
"routing" => [
2024-08-08 04:32:31 +02:00
"eIdentifiers" => [],
2024-07-18 00:53:19 +02:00
"emails" => ["david@invoiceninja.com"]
],
2024-08-22 08:45:06 +02:00
"document" => [
2024-07-16 08:49:18 +02:00
],
2024-07-16 00:31:56 +02:00
];
2024-08-08 04:32:31 +02:00
$payload = array_merge($payload, $override_payload);
2024-08-08 09:48:24 +02:00
$payload['document']['documentType'] = 'invoice';
$payload['document']["rawDocumentData"] = [
2024-08-22 08:45:06 +02:00
"document" => base64_encode($document),
2024-08-08 09:48:24 +02:00
"parse" => true,
2024-08-22 08:45:06 +02:00
"parseStrategy" => "ubl",
2024-08-08 09:48:24 +02:00
];
2024-07-16 08:49:18 +02:00
$uri = "document_submissions";
2024-08-22 08:45:06 +02:00
2024-07-16 00:31:56 +02:00
$r = $this->httpClient($uri, (HttpVerb::POST)->value, $payload, $this->getHeaders());
2024-07-15 09:09:58 +02:00
2024-07-16 08:49:18 +02:00
nlog($r->body());
2024-08-27 06:47:18 +02:00
// nlog($r->json());
2024-07-16 08:49:18 +02:00
2024-08-22 08:45:06 +02:00
if($r->successful()) {
2024-07-15 09:09:58 +02:00
return $r->json()['guid'];
2024-08-22 08:45:06 +02:00
}
2024-07-15 09:09:58 +02:00
2024-08-29 07:25:20 +02:00
return $r;
2024-07-15 09:09:58 +02:00
}
2024-08-27 06:47:18 +02:00
/**
* Get Sending Evidence
*
* @param string $guid
2024-08-28 00:47:28 +02:00
* @return mixed
2024-08-27 06:47:18 +02:00
*/
2024-07-16 00:31:56 +02:00
public function getSendingEvidence(string $guid)
2024-07-15 09:09:58 +02:00
{
2024-07-16 08:49:18 +02:00
$uri = "document_submissions/{$guid}";
2024-08-27 06:47:18 +02:00
2024-07-15 09:09:58 +02:00
$r = $this->httpClient($uri, (HttpVerb::GET)->value, [], $this->getHeaders());
2024-08-27 06:47:18 +02:00
if($r->successful())
return $r->json();
2024-07-15 09:09:58 +02:00
2024-08-28 00:47:28 +02:00
return $r;
2024-08-27 06:47:18 +02:00
}
2024-07-16 04:47:42 +02:00
/**
* CreateLegalEntity
2024-08-22 08:45:06 +02:00
*
2024-08-27 06:47:18 +02:00
* Creates a base entity.
*
* Following creation, you will also need to create a Peppol Identifier
*
2024-07-16 04:47:42 +02:00
* @url https://www.storecove.com/docs/#_openapi_legalentitycreate
2024-08-27 06:47:18 +02:00
*
2024-07-16 04:47:42 +02:00
* @return mixed
*/
2024-08-28 02:48:08 +02:00
public function createLegalEntity(array $data, ?Company $company = null)
2024-07-16 04:47:42 +02:00
{
$uri = 'legal_entities';
2024-08-28 02:48:08 +02:00
if($company){
$data = array_merge([
'city' => $company->settings->city,
'country' => $company->country()->iso_3166_2,
'county' => $company->settings->state,
'line1' => $company->settings->address1,
'line2' => $company->settings->address2,
'party_name' => $company->settings->name,
'tax_registered' => (bool)strlen($company->settings->vat_number ?? '') > 2,
'tenant_id' => $company->company_key,
'zip' => $company->settings->postal_code,
], $data);
}
2024-07-16 04:47:42 +02:00
$company_defaults = [
2024-10-22 02:17:43 +02:00
'acts_as_receiver' => true,
2024-07-16 04:47:42 +02:00
'acts_as_sender' => true,
'advertisements' => ['invoice'],
];
$payload = array_merge($company_defaults, $data);
$r = $this->httpClient($uri, (HttpVerb::POST)->value, $payload);
2024-08-22 08:45:06 +02:00
if($r->successful()) {
2024-07-16 04:47:42 +02:00
return $r->json();
2024-08-22 08:45:06 +02:00
}
2024-07-16 04:47:42 +02:00
return $r;
}
2024-08-27 06:47:18 +02:00
/**
* GetLegalEntity
*
* @param int $id
* @return mixed
*/
2024-07-16 08:49:18 +02:00
public function getLegalEntity($id)
{
2024-08-28 03:12:47 +02:00
// $uri = "legal_entities";
2024-07-16 08:49:18 +02:00
$uri = "legal_entities/{$id}";
$r = $this->httpClient($uri, (HttpVerb::GET)->value, []);
if($r->successful()) {
return $r->json();
}
return $r;
}
2024-08-27 06:47:18 +02:00
/**
* UpdateLegalEntity
*
* @param int $id
* @param array $data
2024-08-30 05:50:03 +02:00
* @return mixed
2024-08-27 06:47:18 +02:00
*/
public function updateLegalEntity(int $id, array $data)
2024-07-16 04:47:42 +02:00
{
$uri = "legal_entities/{$id}";
$r = $this->httpClient($uri, (HttpVerb::PATCH)->value, $data);
if($r->successful()) {
return $r->json();
}
return $r;
}
2024-08-27 06:47:18 +02:00
/**
* AddIdentifier
*
* Add a Peppol identifier to the legal entity
*
* @param int $legal_entity_id
* @param string $identifier
* @param string $scheme
* @return mixed
*/
2024-07-17 07:37:54 +02:00
public function addIdentifier(int $legal_entity_id, string $identifier, string $scheme)
{
$uri = "legal_entities/{$legal_entity_id}/peppol_identifiers";
$data = [
"identifier" => $identifier,
"scheme" => $scheme,
2024-08-22 08:45:06 +02:00
"superscheme" => "iso6523-actorid-upis",
2024-07-17 07:37:54 +02:00
];
$r = $this->httpClient($uri, (HttpVerb::POST)->value, $data);
if($r->successful()) {
2024-08-28 03:12:47 +02:00
$data = $r->json();
2024-08-28 04:13:07 +02:00
2024-08-28 03:12:47 +02:00
return $data;
2024-07-17 07:37:54 +02:00
}
return $r;
}
2024-08-27 06:47:18 +02:00
2024-10-22 02:17:43 +02:00
/**
* addAdditionalTaxIdentifier
*
* Adds an additional TAX identifier to the legal entity, where they are selling cross border
* and are required to be registered in the destination country.
*
* @param int $legal_entity_id
* @param string $identifier
* @param string $scheme
* @return mixed
*/
public function addAdditionalTaxIdentifier(int $legal_entity_id, string $identifier, string $scheme)
{
$uri = "legal_entities/{$legal_entity_id}/additional_tax_identifiers";
$data = [
"identifier" => $identifier,
"scheme" => $scheme,
"superscheme" => "iso6523-actorid-upis",
];
$r = $this->httpClient($uri, (HttpVerb::POST)->value, $data);
if ($r->successful()) {
$data = $r->json();
return $data;
}
return $r;
}
2024-08-27 06:47:18 +02:00
/**
* deleteIdentifier
*
* @param int $legal_entity_id
* @return bool
*/
public function deleteIdentifier(int $legal_entity_id): bool
{
$uri = "/legal_entities/{$legal_entity_id}";
$r = $this->httpClient($uri, (HttpVerb::DELETE)->value, []);
return $r->successful();
}
2024-07-17 07:37:54 +02:00
2024-07-16 04:47:42 +02:00
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2024-07-15 06:27:12 +02:00
private function getHeaders(array $headers = [])
{
return array_merge([
'Accept' => 'application/json',
'Content-type' => 'application/json',
], $headers);
}
2024-08-29 07:25:20 +02:00
/**
* httpClient
*
* @param string $uri
* @param string $verb
* @param array $data
* @param array $headers
* @return \Illuminate\Http\Client\Response
*/
2024-07-16 00:31:56 +02:00
private function httpClient(string $uri, string $verb, array $data, ?array $headers = [])
2024-07-15 06:27:12 +02:00
{
2024-08-22 08:45:06 +02:00
try {
$r = Http::withToken(config('ninja.storecove_api_key'))
->withHeaders($this->getHeaders($headers))
->{$verb}("{$this->base_url}{$uri}", $data)->throw();
2024-08-27 06:47:18 +02:00
}
catch (ClientException $e) {
// 4xx errors
nlog("LEI:: {$this->legal_entity_id}");
2024-08-27 06:47:18 +02:00
nlog("Client error: " . $e->getMessage());
2024-08-28 02:48:08 +02:00
nlog("Response body: " . $e->getResponse()->getBody()->getContents());
2024-08-27 06:47:18 +02:00
} catch (ServerException $e) {
// 5xx errors
nlog("LEI:: {$this->legal_entity_id}");
2024-08-27 06:47:18 +02:00
nlog("Server error: " . $e->getMessage());
2024-08-28 02:48:08 +02:00
nlog("Response body: " . $e->getResponse()->getBody()->getContents());
} catch (\Illuminate\Http\Client\RequestException $e) {
nlog("LEI:: {$this->legal_entity_id}");
2024-08-28 03:12:47 +02:00
nlog("Request error: {$e->getCode()}: " . $e->getMessage());
$responseBody = $e->response->body();
nlog("Response body: " . $responseBody);
return $e->response;
2024-08-27 06:47:18 +02:00
}
2024-07-15 06:27:12 +02:00
2024-08-29 07:25:20 +02:00
return $r; // @phpstan-ignore-line
2024-07-15 06:27:12 +02:00
}
2024-08-22 08:45:06 +02:00
}