Updated the OrderService to utilize the new fromBasket method for creating orders, enhancing code clarity and maintainability. Removed the ProductAvailabilityService as its functionality is now integrated into the ProductRepository.
105 lines
3.9 KiB
PHP
105 lines
3.9 KiB
PHP
<?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)) {
|
|
throw new \InvalidArgumentException('The value cannot be null.');
|
|
}
|
|
|
|
if (! is_string($value)) {
|
|
throw new \InvalidArgumentException('The value must be a string.');
|
|
}
|
|
|
|
$data = Arr::wrap(json_decode($value, true));
|
|
|
|
$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.');
|
|
}
|
|
|
|
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'), []),
|
|
taxRate: TaxRate::fromPercent($taxRate),
|
|
picture: is_string($picture = Arr::get($data, 'picture')) ? $picture : null,
|
|
);
|
|
}
|
|
|
|
/** @param array<string, mixed> $attributes */
|
|
public function set(Model $model, string $key, mixed $value, array $attributes): string
|
|
{
|
|
|
|
if (! ($value instanceof OrderLineProduct)) {
|
|
throw new \InvalidArgumentException('The given value is not an instance of OrderLineProduct.');
|
|
}
|
|
|
|
/** @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);
|
|
}
|
|
}
|