2026-05-17 22:43:52 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace App\Infrastructure\Channel\Ebay;
|
|
|
|
|
|
|
|
|
|
use App\Application\Channel\ChannelAdapterInterface;
|
|
|
|
|
use App\Domain\Article\Article;
|
|
|
|
|
use App\Domain\Article\ArticleCondition;
|
|
|
|
|
use App\Domain\Order\Order;
|
|
|
|
|
|
|
|
|
|
final class EbayAdapter implements ChannelAdapterInterface
|
|
|
|
|
{
|
|
|
|
|
public function __construct(
|
|
|
|
|
private readonly EbayInventoryApiClient $apiClient,
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getType(): string
|
|
|
|
|
{
|
|
|
|
|
return 'ebay';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function publishListing(Article $article): string
|
|
|
|
|
{
|
|
|
|
|
$sku = $article->getSku();
|
|
|
|
|
|
|
|
|
|
$this->apiClient->upsertInventoryItem($sku, [
|
|
|
|
|
'availability' => [
|
|
|
|
|
'shipToLocationAvailability' => [
|
|
|
|
|
'quantity' => $article->getStock(),
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'condition' => $this->mapCondition($article->getCondition()),
|
|
|
|
|
'conditionDescription' => $article->getConditionNotes() ?? '',
|
|
|
|
|
'product' => [
|
|
|
|
|
'title' => $article->getEbayTitle() ?? $article->getSku(),
|
|
|
|
|
'description' => $article->getEbayDescription() ?? '',
|
|
|
|
|
'aspects' => $this->buildAspects($article),
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$offerId = $this->apiClient->createOffer([
|
|
|
|
|
'sku' => $sku,
|
|
|
|
|
'marketplaceId' => 'EBAY_DE',
|
|
|
|
|
'format' => 'FIXED_PRICE',
|
|
|
|
|
'availableQuantity' => $article->getStock(),
|
|
|
|
|
'pricingSummary' => [
|
|
|
|
|
'price' => [
|
|
|
|
|
'currency' => 'EUR',
|
|
|
|
|
'value' => number_format((float) ($article->getListingPrice() ?? '0'), 2, '.', ''),
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'listingDescription' => $article->getEbayDescription() ?? '',
|
|
|
|
|
'categoryId' => $this->getCategoryId(),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return $this->apiClient->publishOffer($offerId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function updateStock(Article $article, int $stock): void
|
|
|
|
|
{
|
|
|
|
|
$this->apiClient->bulkUpdateInventoryItems([
|
|
|
|
|
'requests' => [
|
|
|
|
|
[
|
|
|
|
|
'sku' => $article->getSku(),
|
|
|
|
|
'shipToLocationAvailability' => [
|
|
|
|
|
'quantity' => $stock,
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function deactivateListing(Article $article): void
|
|
|
|
|
{
|
|
|
|
|
$listingId = $article->getEbayListingId();
|
|
|
|
|
if (null === $listingId) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->apiClient->withdrawOffer($listingId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function pushTracking(Order $order): void
|
|
|
|
|
{
|
|
|
|
|
if (null === $order->getTrackingNumber()) {
|
|
|
|
|
throw new \RuntimeException('Order has no tracking number');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->apiClient->addTrackingToOrder($order->getPlatformOrderId(), [
|
|
|
|
|
'lineItems' => [
|
|
|
|
|
['lineItemId' => $order->getPlatformOrderId(), 'quantity' => 1],
|
|
|
|
|
],
|
|
|
|
|
'shippingCarrierCode' => $order->getCarrier() ?? 'DHL',
|
|
|
|
|
'trackingNumber' => $order->getTrackingNumber(),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function mapCondition(ArticleCondition $condition): string
|
|
|
|
|
{
|
|
|
|
|
return match ($condition) {
|
|
|
|
|
ArticleCondition::New => 'NEW',
|
|
|
|
|
ArticleCondition::LikeNew => 'LIKE_NEW',
|
|
|
|
|
ArticleCondition::Good => 'GOOD',
|
|
|
|
|
ArticleCondition::Acceptable => 'ACCEPTABLE',
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @return array<string, list<string>> */
|
|
|
|
|
private function buildAspects(Article $article): array
|
|
|
|
|
{
|
|
|
|
|
$aspects = [];
|
|
|
|
|
foreach ($article->getAttributeValues() as $value) {
|
|
|
|
|
$name = $value->getAttributeDefinition()->getName();
|
|
|
|
|
$aspects[$name] = [$value->getValue()];
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-18 20:34:49 +00:00
|
|
|
foreach ($article->getArticleType()->getEbayAspectFieldMappings() as $ebayName => $fieldKey) {
|
|
|
|
|
$getter = 'get'.ucfirst($fieldKey);
|
|
|
|
|
if (!method_exists($article, $getter)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$fieldValue = $article->$getter();
|
|
|
|
|
if (null !== $fieldValue && '' !== $fieldValue) {
|
|
|
|
|
$aspects[$ebayName] = [(string) $fieldValue];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 22:43:52 +00:00
|
|
|
return $aspects;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function getCategoryId(): string
|
|
|
|
|
{
|
|
|
|
|
return '177';
|
|
|
|
|
}
|
|
|
|
|
}
|