2026-06-14 21:32:07 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace App\Casts;
|
|
|
|
|
|
|
|
|
|
use Domain\Enums\ProductBrand;
|
|
|
|
|
use Domain\Enums\TaxRate;
|
|
|
|
|
use Domain\Enums\Units\OrderUnit;
|
|
|
|
|
use Domain\Models\ValueObjects\Entities\ProductId;
|
|
|
|
|
use Domain\Models\ValueObjects\IncoId;
|
|
|
|
|
use Domain\Models\ValueObjects\OrderLineProduct;
|
|
|
|
|
use Domain\Models\ValueObjects\ProductWeight;
|
|
|
|
|
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
|
use Illuminate\Support\Arr;
|
|
|
|
|
use Ramsey\Uuid\Uuid;
|
|
|
|
|
use Symfony\Component\Uid\Uuid as SymfonyUuid;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @implements CastsAttributes<OrderLineProduct,OrderLineProduct>
|
|
|
|
|
*/
|
|
|
|
|
class OrderLineProductCast implements CastsAttributes
|
|
|
|
|
{
|
|
|
|
|
/** @param array<string, mixed> $attributes */
|
|
|
|
|
public function get(Model $model, string $key, mixed $value, array $attributes): OrderLineProduct
|
|
|
|
|
{
|
|
|
|
|
if (is_null($value)) {
|
2026-10-02 10:53:21 +02:00
|
|
|
throw new \InvalidArgumentException('The value cannot be null.');
|
2026-06-14 21:32:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! is_string($value)) {
|
2026-10-02 10:53:21 +02:00
|
|
|
throw new \InvalidArgumentException('The value must be a string.');
|
2026-06-14 21:32:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$data = Arr::wrap(json_decode($value, true));
|
|
|
|
|
|
2026-10-29 20:21:32 +01:00
|
|
|
$taxRate = Arr::get($data, 'tax_rate');
|
|
|
|
|
$taxRate = is_numeric($taxRate) ? (float) $taxRate : null;
|
|
|
|
|
|
|
|
|
|
if (is_null($taxRate)) {
|
|
|
|
|
throw new \InvalidArgumentException('The tax rate cannot be null.');
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-14 21:32:07 +02:00
|
|
|
return new OrderLineProduct(
|
|
|
|
|
incoId: new IncoId(Arr::integer($data, 'inco_id')),
|
|
|
|
|
originalId: new ProductId(Uuid::fromString(
|
|
|
|
|
SymfonyUuid::fromString(Arr::string($data, 'original_id'))->toRfc4122()
|
|
|
|
|
)),
|
|
|
|
|
name: Arr::string($data, 'name'),
|
|
|
|
|
weight: new ProductWeight(
|
|
|
|
|
value: Arr::integer($data, 'weight'),
|
|
|
|
|
isVariable: Arr::boolean($data, 'weight_variable'),
|
|
|
|
|
),
|
|
|
|
|
brand: ProductBrand::from(Arr::string($data, 'brand')),
|
|
|
|
|
orderUnit: OrderUnit::from(Arr::string($data, 'order_unit')),
|
|
|
|
|
price: new MoneyCast()->get($model, 'price', Arr::get($data, 'price'), []),
|
|
|
|
|
discountedPrice: new MoneyCast()->get($model, 'discounted_price', Arr::get($data, 'discounted_price'), []),
|
|
|
|
|
priceKgTtc: new MoneyCast()->get($model, 'price_kg_ttc', Arr::get($data, 'price_kg_ttc'), []),
|
2026-10-29 20:21:32 +01:00
|
|
|
taxRate: TaxRate::fromPercent($taxRate),
|
|
|
|
|
picture: is_string($picture = Arr::get($data, 'picture')) ? $picture : null,
|
2026-06-14 21:32:07 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @param array<string, mixed> $attributes */
|
|
|
|
|
public function set(Model $model, string $key, mixed $value, array $attributes): string
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (! ($value instanceof OrderLineProduct)) {
|
2026-10-02 10:53:21 +02:00
|
|
|
throw new \InvalidArgumentException('The given value is not an instance of OrderLineProduct.');
|
2026-06-14 21:32:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @var OrderLineProduct $value */
|
|
|
|
|
|
|
|
|
|
return json_encode([
|
|
|
|
|
'inco_id' => $value->incoId->value,
|
|
|
|
|
'original_id' => $value->originalId->value,
|
|
|
|
|
'name' => $value->name,
|
|
|
|
|
'weight' => $value->weight->value,
|
|
|
|
|
'weight_variable' => $value->weight->isVariable,
|
|
|
|
|
'brand' => $value->brand->value,
|
|
|
|
|
'order_unit' => $value->orderUnit->value,
|
|
|
|
|
'price' => new MoneyCast()->set(
|
|
|
|
|
$model,
|
|
|
|
|
'price',
|
|
|
|
|
$value->price,
|
|
|
|
|
[]
|
|
|
|
|
),
|
|
|
|
|
'discounted_price' => new MoneyCast()->set(
|
|
|
|
|
$model,
|
|
|
|
|
'discounted_price',
|
|
|
|
|
$value->discountedPrice,
|
|
|
|
|
[]
|
|
|
|
|
),
|
|
|
|
|
'price_kg_ttc' => new MoneyCast()->set(
|
|
|
|
|
$model,
|
|
|
|
|
'price_kg_ttc',
|
|
|
|
|
$value->priceKgTtc,
|
|
|
|
|
[]
|
|
|
|
|
),
|
|
|
|
|
'tax_rate' => $value->taxRate->percent(),
|
|
|
|
|
'picture' => $value->picture,
|
|
|
|
|
], \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES);
|
|
|
|
|
}
|
|
|
|
|
}
|