Files
2026-09-15 10:35:56 +08:00

109 lines
4.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Esun\LingxingErp\Model\Order;
use Esun\LingxingErp\Model\Config;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Store\Model\StoreManagerInterface;
class OrderPayloadBuilder
{
/**
* Lingxing API documentation:
* https://apidoc.lingxing.com/#/docs/hide/CreateOrdersV2.md
*/
public function __construct(
private readonly Config $config,
private readonly StoreManagerInterface $storeManager
) {
}
public function build(OrderInterface $order): array
{
$websiteId = (int)$this->storeManager->getStore((int)$order->getStoreId())->getWebsiteId();
$this->config->assertOrderMappingReady($websiteId);
$address = $order->getShippingAddress() ?: $order->getBillingAddress();
if ($address === null) {
throw new \RuntimeException('Magento order has no shipping or billing address.');
}
$items = [];
foreach ($order->getAllVisibleItems() as $item) {
if ($item->getIsVirtual()) {
continue;
}
$sku = trim((string)$item->getSku());
if ($sku === '') {
throw new \RuntimeException('Magento order item has an empty SKU.');
}
$items[] = [
'msku' => $sku,
'quantity' => (int)$item->getQtyOrdered(),
'unit_price' => (float)$item->getPrice(),
'stock_deduction_type' => $this->config->getStockDeductionType(),
];
}
if ($items === []) {
throw new \RuntimeException('Magento order has no physical SKU to export.');
}
$street = $address->getStreet();
$streetLines = array_values(array_filter(array_map(
static fn ($line): string => trim((string)$line),
is_array($street) ? $street : [(string)$street]
), static fn (string $line): bool => $line !== ''));
$receiverName = trim((string)$address->getFirstname() . ' ' . (string)$address->getLastname());
$buyerName = trim(implode(' ', array_filter([
trim((string)$order->getCustomerFirstname()),
trim((string)$order->getCustomerMiddlename()),
trim((string)$order->getCustomerLastname()),
], static fn (string $part): bool => $part !== '')));
$buyerEmail = trim((string)$order->getCustomerEmail());
if ($buyerEmail === '') {
$buyerEmail = trim((string)$address->getEmail());
}
$orderData = [
'platform_order_no' => (string)$order->getIncrementId(),
'receiver_country_code' => (string)$address->getCountryId(),
'customer_shipping_amount' => (float)$order->getShippingAmount(),
'customer_tax_amount' => (float)$order->getTaxAmount(),
'order_total_amount' => (float)$order->getGrandTotal(),
'global_purchase_time' => (new \DateTimeImmutable((string)$order->getCreatedAt(), new \DateTimeZone('UTC')))->getTimestamp(),
'receiver_name' => $receiverName,
'receiver_company_name' => (string)$address->getCompany(),
'city' => (string)$address->getCity(),
'address_line1' => $streetLines[0] ?? '',
'amount_currency' => (string)$order->getOrderCurrencyCode(),
'items' => $items,
];
$optionalAddressData = [
'state_or_region' => trim((string)$address->getRegion()),
'postal_code' => trim((string)$address->getPostcode()),
'address_line2' => $streetLines[1] ?? '',
'address_line3' => count($streetLines) > 2 ? implode(' ', array_slice($streetLines, 2)) : '',
'receiver_mobile' => trim((string)$address->getTelephone()),
'buyer_email' => $buyerEmail,
'buyer_name' => $buyerName !== '' ? $buyerName : $receiverName,
];
foreach ($optionalAddressData as $field => $value) {
if ($value !== '') {
$orderData[$field] = $value;
}
}
if ((string)$order->getCustomerNote() !== '') {
$orderData['buyer_note'] = (string)$order->getCustomerNote();
}
if ($this->config->getWarehouseId($websiteId) !== '') {
$orderData['wid'] = $this->config->getWarehouseId($websiteId);
$orderData['logistics_type_id'] = $this->config->getLogisticsTypeId($websiteId);
}
return [
'platform_code' => $this->config->getPlatformCode($websiteId),
'store_id' => $this->config->getLingxingStoreId($websiteId),
'orders' => [$orderData],
];
}
}