feat: add Snipe-IT asset synchronization
This commit is contained in:
86
app/Integrations/SnipeIt/SnipeItAssetMapper.php
Normal file
86
app/Integrations/SnipeIt/SnipeItAssetMapper.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Integrations\SnipeIt;
|
||||
|
||||
use App\Integrations\SnipeIt\Data\AssetData;
|
||||
use App\Integrations\SnipeIt\Exceptions\SnipeItMappingException;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Illuminate\Support\Arr;
|
||||
use Throwable;
|
||||
|
||||
final class SnipeItAssetMapper
|
||||
{
|
||||
/** @param array<string, mixed> $row */
|
||||
public function map(array $row): AssetData
|
||||
{
|
||||
$id = $this->integer($row['id'] ?? null);
|
||||
$assetTag = $this->text($row['asset_tag'] ?? null);
|
||||
|
||||
if ($id === null || $id < 1 || $assetTag === null) {
|
||||
throw new SnipeItMappingException('A resposta do Snipe-IT contém um ativo sem ID ou etiqueta válida.');
|
||||
}
|
||||
|
||||
$modelName = $this->text(Arr::get($row, 'model.name'));
|
||||
|
||||
return new AssetData(
|
||||
snipeAssetId: $id,
|
||||
assetTag: $assetTag,
|
||||
name: $this->text($row['name'] ?? null) ?? $modelName ?? $assetTag,
|
||||
serial: $this->text($row['serial'] ?? null),
|
||||
modelId: $this->integer(Arr::get($row, 'model.id')),
|
||||
modelName: $modelName,
|
||||
categoryId: $this->integer(Arr::get($row, 'category.id')),
|
||||
categoryName: $this->text(Arr::get($row, 'category.name')),
|
||||
manufacturer: $this->text(Arr::get($row, 'manufacturer.name')),
|
||||
statusId: $this->integer(Arr::get($row, 'status_label.id')),
|
||||
statusName: $this->text(Arr::get($row, 'status_label.name')),
|
||||
locationId: $this->integer(Arr::get($row, 'rtd_location.id') ?? Arr::get($row, 'location.id')),
|
||||
locationName: $this->text(Arr::get($row, 'rtd_location.name') ?? Arr::get($row, 'location.name')),
|
||||
requestable: $this->boolean($row['requestable'] ?? false),
|
||||
assignedType: $this->text(Arr::get($row, 'assigned_to.type')),
|
||||
assignedId: $this->integer(Arr::get($row, 'assigned_to.id')),
|
||||
imageUrl: $this->text($row['image'] ?? $row['image_url'] ?? null),
|
||||
sourceUpdatedAt: $this->date(Arr::get($row, 'updated_at.datetime') ?? Arr::get($row, 'updated_at.date') ?? $row['updated_at'] ?? null),
|
||||
);
|
||||
}
|
||||
|
||||
private function text(mixed $value): ?string
|
||||
{
|
||||
if (! is_scalar($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$decoded = trim(html_entity_decode((string) $value, ENT_QUOTES | ENT_HTML5, 'UTF-8'));
|
||||
|
||||
return $decoded === '' ? null : $decoded;
|
||||
}
|
||||
|
||||
private function integer(mixed $value): ?int
|
||||
{
|
||||
return is_numeric($value) ? (int) $value : null;
|
||||
}
|
||||
|
||||
private function boolean(mixed $value): bool
|
||||
{
|
||||
if (is_bool($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return in_array(strtolower((string) $value), ['1', 'true', 'yes', 'sim'], true);
|
||||
}
|
||||
|
||||
private function date(mixed $value): ?CarbonImmutable
|
||||
{
|
||||
$text = $this->text($value);
|
||||
|
||||
if ($text === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return CarbonImmutable::parse($text);
|
||||
} catch (Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user