109 lines
4.6 KiB
PHP
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],
|
|
];
|
|
}
|
|
}
|