SuperSeller3000/src/Infrastructure/Channel/Ebay/EbayAdapter.php

138 lines
4.2 KiB
PHP
Raw Normal View History

<?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()];
}
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];
}
}
return $aspects;
}
private function getCategoryId(): string
{
return '177';
}
}