662 lines
26 KiB
PHP
662 lines
26 KiB
PHP
<?php
|
||
/**
|
||
* Copyright © All rights reserved.
|
||
* See COPYING.txt for license details.
|
||
*/
|
||
declare(strict_types=1);
|
||
|
||
namespace Lts\Sales\Console\Command;
|
||
|
||
use JR\NetSuite\Lib\Restful\NetSuiteAPI;
|
||
use JR\NetSuite\Logger\Logger;
|
||
use Lts\Netterm\Model\Payment\Netterm;
|
||
use Lts\Sales\Netsuite\ShippingMethodMapping;
|
||
use Magento\Catalog\Api\ProductRepositoryInterface;
|
||
use Magento\Customer\Api\CustomerRepositoryInterface;
|
||
use Magento\Customer\Api\Data\CustomerInterface;
|
||
use Magento\Framework\Api\SearchCriteriaBuilderFactory;
|
||
use Magento\Framework\Exception\InvalidArgumentException;
|
||
use Magento\Framework\Exception\LocalizedException;
|
||
use Magento\Framework\Exception\NoSuchEntityException;
|
||
use Magento\Inventory\Model\Source\Command\GetList;
|
||
use Magento\InventoryApi\Api\Data\SourceItemInterface;
|
||
use Magento\InventoryApi\Api\SourceItemRepositoryInterface;
|
||
use Magento\InventoryDistanceBasedSourceSelection\Model\DistanceProvider\GetDistanceFromSourceToAddress;
|
||
use Magento\InventoryInStorePickupSales\Model\Order\GetPickupLocationCode;
|
||
use Magento\InventorySourceSelectionApi\Api\Data\AddressInterfaceFactory;
|
||
use Magento\Quote\Api\CartRepositoryInterface;
|
||
use Magento\Quote\Api\Data\CartInterface;
|
||
use Magento\Sales\Api\Data\OrderInterface;
|
||
use Magento\Sales\Api\Data\OrderItemInterface;
|
||
use Magento\Sales\Api\OrderRepositoryInterface;
|
||
use Magento\Sales\Model\ResourceModel\Order\Collection;
|
||
use Magento\InventoryApi\Api\Data\SourceInterface;
|
||
use Psr\Log\LoggerInterface;
|
||
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
|
||
use Symfony\Component\Console\Command\Command;
|
||
use Symfony\Component\Console\Input\InputInterface;
|
||
use Symfony\Component\Console\Input\InputOption;
|
||
use Symfony\Component\Console\Output\OutputInterface;
|
||
|
||
class OrderNetsuiteSync extends Command
|
||
{
|
||
private Logger $logger;
|
||
private Collection $orderCollection;
|
||
|
||
private OrderInterface $order;
|
||
private CartRepositoryInterface $cartRepository;
|
||
private ?CartInterface $quote = null;
|
||
private GetPickupLocationCode $getPickupLocationCode;
|
||
|
||
/**
|
||
* @var SourceInterface[]
|
||
*/
|
||
private array $sources = [];
|
||
private GetList $getList;
|
||
private ProductRepositoryInterface $productRepository;
|
||
private NetSuiteAPI $netSuiteAPI;
|
||
|
||
const HUB_REPOSITORY_CODE = ['CA-LA', 'TX', 'NJ-MountLaurel'];
|
||
|
||
const NETSUITE_CREDIT_CARD_PAYMENT_ID = '12';
|
||
const NETSUITE_SALES_ORDER_SERVICE = 'record/v1/salesOrder';
|
||
const NETSUITE_CUSTOMER_DEPOSIT_SERVICE = 'record/v1/customerDeposit';
|
||
private OrderRepositoryInterface $orderRepository;
|
||
|
||
const DEFAULT_INVENTORY_SOURCE = 'default';
|
||
private SourceItemRepositoryInterface $sourceItemRepository;
|
||
private SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory;
|
||
private AddressInterfaceFactory $addressInterfaceFactory;
|
||
private GetDistanceFromSourceToAddress $getDistanceFromSourceToAddress;
|
||
private CustomerRepositoryInterface $customerRepository;
|
||
private ?CustomerInterface $customer = null;
|
||
private LoggerInterface $magentoLogger;
|
||
|
||
private InputInterface $input;
|
||
private OutputInterface $output;
|
||
/**
|
||
* @param Logger $logger
|
||
* @param Collection $orderCollection
|
||
* @param CartRepositoryInterface $cartRepository
|
||
* @param GetPickupLocationCode $getPickupLocationCode
|
||
* @param GetList $getList
|
||
* @param ProductRepositoryInterface $productRepository
|
||
* @param NetSuiteAPI $netSuiteAPI
|
||
* @param OrderRepositoryInterface $orderRepository
|
||
* @param SourceItemRepositoryInterface $sourceItemRepository
|
||
* @param SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory
|
||
* @param GetDistanceFromSourceToAddress $getDistanceFromSourceToAddress
|
||
* @param AddressInterfaceFactory $addressInterfaceFactory
|
||
*/
|
||
public function __construct(
|
||
Logger $logger,
|
||
Collection $orderCollection,
|
||
CartRepositoryInterface $cartRepository,
|
||
GetPickupLocationCode $getPickupLocationCode,
|
||
GetList $getList,
|
||
ProductRepositoryInterface $productRepository,
|
||
NetSuiteAPI $netSuiteAPI,
|
||
OrderRepositoryInterface $orderRepository,
|
||
SourceItemRepositoryInterface $sourceItemRepository,
|
||
SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory,
|
||
GetDistanceFromSourceToAddress $getDistanceFromSourceToAddress,
|
||
AddressInterfaceFactory $addressInterfaceFactory,
|
||
CustomerRepositoryInterface $customerRepository,
|
||
LoggerInterface $magentoLogger
|
||
) {
|
||
$this->logger = $logger;
|
||
$this->orderCollection = $orderCollection;
|
||
$this->cartRepository = $cartRepository;
|
||
$this->getPickupLocationCode = $getPickupLocationCode;
|
||
$this->getList = $getList;
|
||
|
||
$this->productRepository = $productRepository;
|
||
$this->netSuiteAPI = $netSuiteAPI;
|
||
$this->orderRepository = $orderRepository;
|
||
$this->sourceItemRepository = $sourceItemRepository;
|
||
$this->searchCriteriaBuilderFactory = $searchCriteriaBuilderFactory;
|
||
$this->addressInterfaceFactory = $addressInterfaceFactory;
|
||
$this->getDistanceFromSourceToAddress = $getDistanceFromSourceToAddress;
|
||
$this->customerRepository = $customerRepository;
|
||
$this->magentoLogger = $magentoLogger;
|
||
$this->getInventorySources();
|
||
parent::__construct();
|
||
}
|
||
|
||
protected function configure()
|
||
{
|
||
$this->setName('order:netsuite:sync');
|
||
$this->setDescription('Sync order to netsuite manually, separate multiple order id with comma.');
|
||
$this->addOption(
|
||
'ordersId',
|
||
'ordersId',
|
||
InputOption::VALUE_REQUIRED,
|
||
",\r\n
|
||
ordersId is required\r\n"
|
||
);
|
||
}
|
||
|
||
/**
|
||
* @return array
|
||
*/
|
||
protected function getInventorySources()
|
||
{
|
||
if (empty($this->sources)) {
|
||
foreach ($this->getList->execute()->getItems() as $item) {
|
||
$this->sources[$item->getSourceCode()] = $item;
|
||
}
|
||
}
|
||
|
||
return $this->sources;
|
||
}
|
||
|
||
/**
|
||
* @throws LocalizedException
|
||
*/
|
||
protected function getCardInfo()
|
||
{
|
||
$payment = $this->order->getPayment();
|
||
$billingAddress = $this->order->getBillingAddress();
|
||
$paymentMethod = $payment->getMethodInstance();
|
||
if ($paymentMethod->isOffline()) {
|
||
return '';
|
||
}
|
||
|
||
return $payment->getCcType().': '.$payment->getCcLast4().', '.
|
||
$billingAddress->getFirstname().' '.$billingAddress->getLastname().': '.
|
||
implode(' ', $billingAddress->getStreet()).', '.
|
||
$billingAddress->getCity().', '.$billingAddress->getRegion() .', '.$billingAddress->getPostcode();
|
||
|
||
}
|
||
|
||
protected function getProductNetsuiteId(int $productId)
|
||
{
|
||
try {
|
||
$product = $this->productRepository->getById($productId);
|
||
return $product->getNetsuiteId();
|
||
} catch (NoSuchEntityException $e) {
|
||
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* @param string $pickupLocationCode
|
||
* @return array
|
||
*/
|
||
protected function getNetsuiteOrderItems(string $pickupLocationCode)
|
||
{
|
||
$data = [];
|
||
if (!empty($pickupLocationCode)) {
|
||
foreach ($this->order->getAllVisibleItems() as $item) {
|
||
/* @var $item OrderItemInterface */
|
||
$data[$item->getItemId()] = [
|
||
'item' => ['id' => $this->getProductNetsuiteId((int)$item->getProductId())],
|
||
'rate' => $this->numberFormat($item->getPrice()),
|
||
'sku' => $item->getSku(),
|
||
'quantity' => $item->getQtyOrdered()*1.0
|
||
];
|
||
}
|
||
}
|
||
|
||
return $data;
|
||
}
|
||
|
||
/**
|
||
* 拆单规则:
|
||
* 在checkout的时候,如果客户选择ship out,我们首先看哪个hub有相对应的库存,如果每一个hub都有货,那我们就根据shipping address的
|
||
* region来确定哪个hub出货。譬如旧金山下单了,三个hub都有货,那我们优先从西部的hub(洛杉矶)出货。假如说三个hub都没货,那我们就优先从
|
||
* 有货的warehouse出,如果有多个仓库有货的话还是按照region来。
|
||
*
|
||
* 如果没有一个仓库能满足整张单的库存量的话,那我们就会拆单。具体的选择仓库或者hub的逻辑还是按照上面的那个来,哪个能fulfill的多的就从哪
|
||
* 一个出,如果有多个的话就距离优先。如果可以的话,可以在M2就拆成两张单吗?税的话应该怎么拆都不会变,因为都是按照销售的物品来的。运费的话
|
||
* 我们是这样子想的,如果拆成两张单,我们只会收客户两张单里面运费高的那一份运费,剩下的运费我们自己承担。
|
||
*
|
||
* hub的话是指我们三个大仓库,分别是LA,TX,NJ,
|
||
*
|
||
* 如果客户选择pickup的话,如果他选择的preferred warehouse里面有库存的话那就直接可以process;如果没有的话,我们就会提示客户说当前物
|
||
* 品在你preferred warehouse没有库存,你可以选择配送或者把缺货商品从购物车里移除
|
||
*
|
||
* (1) 关于订单同步到netsuite时的拆单
|
||
* (1.1)根据上述规则拆单
|
||
* (1.2)运费可以放在其中一张单上
|
||
* (1.3)订单金额根据拆单后的产品的金额计算
|
||
* (1.4)税可以不用给
|
||
*
|
||
* @return array
|
||
*/
|
||
protected function getSyncOrders()
|
||
{
|
||
/* @var $info string | null */
|
||
// $information = $this->order->getData('additional_information');
|
||
// if ($information) {
|
||
// $info = json_decode($information, true);
|
||
// if (is_array($info) && !empty($info['syncOrders'])) {
|
||
// return $info['syncOrders'];
|
||
// }
|
||
// }
|
||
|
||
$pickupLocationCode = $this->getPickupLocationCode->execute($this->order);
|
||
if ($pickupLocationCode) {
|
||
return [$pickupLocationCode => $this->getNetsuiteOrderItems($pickupLocationCode)];
|
||
}
|
||
|
||
return $this->orderSplit();
|
||
}
|
||
|
||
/**
|
||
* @param string|float $number
|
||
* @return float
|
||
*/
|
||
protected function numberFormat(string | float $number)
|
||
{
|
||
return number_format($number*1.0, 2, '.', '')*1.0;
|
||
}
|
||
/**
|
||
* order split
|
||
* @return array
|
||
*/
|
||
protected function orderSplit()
|
||
{
|
||
$result = [];
|
||
foreach ($this->order->getAllItems() as $item) {
|
||
/* @var $item OrderItemInterface */
|
||
if ($item->getProductType()===Configurable::TYPE_CODE){
|
||
continue;
|
||
}
|
||
$inventorySourceFromProduct = $this->getInventorySourceFromProduct($item);
|
||
|
||
foreach ($inventorySourceFromProduct as $sourceCode =>$splitItem) {
|
||
$result[$sourceCode][$item->getItemId()] = [
|
||
'item' => ['id' => $this->getProductNetsuiteId((int)$item->getProductId())],
|
||
'rate' => $this->numberFormat($item->getPrice()),
|
||
'sku' => $item->getSku(),
|
||
'quantity' => $splitItem[$item->getItemId()]*1.0
|
||
];
|
||
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* @param OrderItemInterface $orderItem
|
||
* @return float[][]
|
||
*/
|
||
protected function getInventorySourceFromProduct(OrderItemInterface $orderItem)
|
||
{
|
||
$searchCriteria = $this->searchCriteriaBuilderFactory->create()
|
||
->addFilter(SourceItemInterface::SKU, $orderItem->getSku())
|
||
->addFilter(SourceItemInterface::SOURCE_CODE, self::DEFAULT_INVENTORY_SOURCE, 'neq')
|
||
->create();
|
||
|
||
$sourceItems = $this->sourceItemRepository->getList($searchCriteria)->getItems();
|
||
$availableItems = [];
|
||
|
||
$distances = [];
|
||
$oneSource = false;
|
||
|
||
foreach ($sourceItems as $sourceItem) {
|
||
$sourceAddress = $this->addressTransform($this->order->getShippingAddress());
|
||
|
||
$distances[$sourceItem->getSourceCode()] = $distance = $this->getDistanceFromSourceToAddress->execute(
|
||
$this->sources[$sourceItem->getSourceCode()],
|
||
$sourceAddress
|
||
);
|
||
|
||
if ($sourceItem->getQuantity() >= $orderItem->getQtyOrdered()) {
|
||
$oneSource = true;
|
||
$availableItems[$distance] = [
|
||
'sourceItem' => $sourceItem,
|
||
'isHub' => in_array($sourceItem->getSourceCode(), self::HUB_REPOSITORY_CODE),
|
||
];
|
||
}
|
||
}
|
||
|
||
//one warehouse inventory is not enough for this order product
|
||
if (empty($availableItems)) {
|
||
foreach ($sourceItems as $sourceItem) {
|
||
$availableItems[$distances[$sourceItem->getSourceCode()]] = [
|
||
'sourceItem' => $sourceItem,
|
||
'isHub' => in_array($sourceItem->getSourceCode(), self::HUB_REPOSITORY_CODE)
|
||
];
|
||
}
|
||
}
|
||
|
||
ksort($availableItems);
|
||
// $warehouseDistances = [];
|
||
// foreach ($availableItems as $distance => $items) {
|
||
// $warehouseDistances[] = [
|
||
// 'product'=>$orderItem->getSku(),
|
||
// 'warehouse code'=>$items['sourceItem']->getSourceCode(),
|
||
// 'warehouse_stock' => $items['sourceItem']->getQuantity(),
|
||
// 'distance'=>$distance,
|
||
// 'isHub' => $items['isHub']
|
||
// ];
|
||
// }
|
||
// $this->logger->debug('distance on warehouse: ', $warehouseDistances);
|
||
return $this->getPreferredInventorySource($availableItems, $orderItem, $oneSource);
|
||
}
|
||
|
||
/**
|
||
* choose preferred warehouse for ordered product
|
||
*/
|
||
protected function getPreferredInventorySource(array $availableItems, OrderItemInterface $orderItem, bool $oneSource)
|
||
{
|
||
$hub = [];
|
||
$other = [];
|
||
$qty = $orderItem->getQtyOrdered();
|
||
foreach ($availableItems as $availableItem) {
|
||
if ($availableItem['isHub']) {
|
||
$hub[] = $availableItem;
|
||
} else {
|
||
$other[] = $availableItem;
|
||
}
|
||
}
|
||
|
||
//if one warehouse stock is enough for this ordered product, then return
|
||
if ($oneSource === true) {
|
||
$source = !empty($hub)? current($hub):current($other);
|
||
// $source['qty'] = $qty;
|
||
return [$source['sourceItem']->getSourceCode() => [$orderItem->getItemId() => $qty]];
|
||
}
|
||
|
||
$aggregation = [];
|
||
$total = 0;
|
||
foreach ($availableItems as $item) {
|
||
if ($total < $qty) {
|
||
$aggregation[$item['sourceItem']->getSourceCode()] = $item['sourceItem']->getQuantity();
|
||
}
|
||
$total += $item['sourceItem']->getQuantity();
|
||
}
|
||
|
||
return $this->correctLastWarehouseQty($aggregation, $orderItem);
|
||
}
|
||
|
||
/**
|
||
* @param array $availableItems
|
||
* @param OrderItemInterface $orderItem
|
||
* @return array
|
||
*/
|
||
protected function correctLastWarehouseQty(array $availableItems, OrderItemInterface $orderItem)
|
||
{
|
||
|
||
$lastKey = array_key_last($availableItems);
|
||
$qty = $orderItem->getQtyOrdered();
|
||
$lastQty = $qty;
|
||
$data = [];
|
||
foreach ($availableItems as $sourceCode => $qty) {
|
||
if ($sourceCode != $lastKey) {
|
||
$lastQty -= $qty;
|
||
} else {
|
||
$availableItems[$lastKey] = $lastQty;
|
||
}
|
||
$data[$sourceCode][$orderItem->getItemId()] = $availableItems[$sourceCode];
|
||
}
|
||
|
||
return $data;
|
||
}
|
||
|
||
/**
|
||
* transform order address to the calculate distance address
|
||
* @param \Magento\Sales\Api\Data\OrderAddressInterface $address
|
||
* @return \Magento\InventorySourceSelectionApi\Api\Data\AddressInterface
|
||
*/
|
||
protected function addressTransform(\Magento\Sales\Api\Data\OrderAddressInterface $address) {
|
||
if ($address->getStreet()) {
|
||
$streets = implode(' ', $address->getStreet());
|
||
}
|
||
return $this->addressInterfaceFactory->create([
|
||
'country' => $address->getCountryId() ?? '',
|
||
'postcode' => $address->getPostcode() ?? '',
|
||
'street' => $streets ?? '',
|
||
'region' => $address->getRegion() ?? '',
|
||
'city' => $address->getCity() ?? ''
|
||
]);
|
||
}
|
||
|
||
protected function getShippingAddress()
|
||
{
|
||
$shippingAddress = $this->order->getShippingAddress();
|
||
$streets = ['', ''];
|
||
if ($shippingAddress->getStreet()) {
|
||
$streets = $shippingAddress->getStreet();
|
||
}
|
||
return [
|
||
'country' => ['id' => 'US'],
|
||
'addr1' => $streets[0],
|
||
'addr2' => $streets[1] ?? '',
|
||
'city' => $shippingAddress->getCity(),
|
||
'state' => $shippingAddress->getRegionCode(),
|
||
'zip' => $shippingAddress->getPostcode(),
|
||
'addressee' => $shippingAddress->getFirstname() . ' ' . $shippingAddress->getLastname(),
|
||
'attention' => null,
|
||
'addrPhone' => $shippingAddress->getTelephone(),
|
||
'override' => false
|
||
];
|
||
}
|
||
|
||
/**
|
||
* @return string
|
||
* @throws NoSuchEntityException
|
||
*/
|
||
protected function getTerms()
|
||
{
|
||
$payment = $this->order->getPayment();
|
||
if ($payment->getMethod() == NetTerm::PAYMENT_METHOD_NETTERM_CODE) {
|
||
return $this->getQuote()->getNetsuitePaymentId();
|
||
}
|
||
|
||
return self::NETSUITE_CREDIT_CARD_PAYMENT_ID;
|
||
}
|
||
|
||
protected function getCustomer() {
|
||
if ($this->customer) {
|
||
return $this->customer;
|
||
}
|
||
if ($this->order->getCustomer()) {
|
||
$this->customer = $this->order->getCustomer()->getDataModel();
|
||
}
|
||
|
||
$this->customer = $this->customerRepository->getById($this->order->getCustomerId());
|
||
|
||
return $this->customer;
|
||
}
|
||
protected function getPostData(string $locationId, array $items, int $index)
|
||
{
|
||
$dataCustomer = $this->getCustomer();
|
||
|
||
$shippingAddress = $this->order->getShippingAddress();
|
||
$shippingCost = 0;
|
||
if ($index == 1) {
|
||
$shippingCost = $this->numberFormat($this->order->getShippingAmount());
|
||
}
|
||
|
||
foreach ($items as &$item) {
|
||
unset($item['sku']);
|
||
}
|
||
|
||
return [
|
||
'externalId'=> 'Magento-'.$this->order->getEntityId().'-'.$index,
|
||
'entity' => [
|
||
'id'=>$dataCustomer->getCustomAttribute('netsuite_id')->getValue(),
|
||
],
|
||
|
||
'terms' => ['id' => $this->getTerms()],
|
||
'otherRefNum' => $this->getQuote()->getOtherRefNum(),
|
||
'custbody_il_email' => $shippingAddress->getEmail(),
|
||
'custbody_il_phone' => $shippingAddress->getTelephone(),
|
||
'custbody_card_info' => $this->getCardInfo(),
|
||
'custbody_ecommerce_order_no' => 'Magento-'.$this->order->getIncrementId().'-'.$index,
|
||
'subsidiary' => ['id'=> 3],
|
||
'cseg_ncg_rep_office' => ['id'=> 13],
|
||
'location' => ['id'=> $locationId],
|
||
'custbody_location_filter' => 'RMA',
|
||
// 'discountItem' => ['id'=> -6],
|
||
// 'discountRate' => 6.17,
|
||
'shipMethod' => ['id'=> ShippingMethodMapping::getShippingMethodId($this->order->getShippingMethod())],
|
||
'shippingCost' => $shippingCost,
|
||
'shipAddressList' => ['id'=>-2],
|
||
'shipIsResidential' => false,
|
||
'shippingAddress' => $this->getShippingAddress(),
|
||
'item' => ['items'=>$items],
|
||
];
|
||
}
|
||
|
||
/**
|
||
* @return CartInterface
|
||
* @throws NoSuchEntityException
|
||
*/
|
||
protected function getQuote()
|
||
{
|
||
if (!$this->quote) {
|
||
$this->quote = $this->cartRepository->get($this->order->getQuoteId());
|
||
}
|
||
|
||
return $this->quote;
|
||
}
|
||
|
||
/**
|
||
* @return \Magento\Sales\Api\Data\OrderSearchResultInterface]
|
||
*/
|
||
protected function getWaitSyncOrders()
|
||
{
|
||
$ordersId = explode(',', $this->input->getOption('ordersId'));
|
||
$this->output->writeln('received orders id: '.implode(',', $ordersId));
|
||
$criteria = $this->searchCriteriaBuilderFactory->create()
|
||
->addFilter('is_netsuite_sync', 0)
|
||
->addFilter('entity_id', $ordersId, 'in')
|
||
->create();
|
||
return $this->orderRepository->getList($criteria);
|
||
}
|
||
|
||
protected function customerDepositBuild()
|
||
{
|
||
$dataCustomer = $this->getCustomer();
|
||
return [
|
||
'externalId'=> 'CD-'.$this->order->getEntityId().'-1',
|
||
'customer' => ['id' => $dataCustomer->getCustomAttribute('netsuite_id')?->getValue()],
|
||
'salesOrder' => ['externalId' => 'Magento-'.$this->order->getEntityId().'-1'],
|
||
'payment' => $this->numberFormat($this->order->getGrandTotal())
|
||
];
|
||
}
|
||
|
||
/**
|
||
* @param OrderInterface $order
|
||
* @return $this
|
||
*/
|
||
public function setOrder(OrderInterface $order)
|
||
{
|
||
$this->order = $order;
|
||
return $this;
|
||
}
|
||
|
||
/**
|
||
* @return array
|
||
*/
|
||
public function customerDepositSync()
|
||
{
|
||
$res = [];
|
||
try {
|
||
$paymentMethod = $this->order->getPayment()->getMethodInstance();
|
||
if (!$paymentMethod->isOffline()) {
|
||
$postData = $this->customerDepositBuild();
|
||
$response = $this->netSuiteAPI->postData(self::NETSUITE_CUSTOMER_DEPOSIT_SERVICE, $postData);
|
||
if ($response['error'] == true){
|
||
$message = sprintf('customer deposit %s sync to Netsuite fail', $this->order->getIncrementId());
|
||
$this->output->writeln($message);
|
||
$this->output->writeln(sprintf('customer deposit %s sync response: %s', $this->order->getIncrementId(), json_encode($response)));
|
||
$this->output->writeln(sprintf('customer deposit %s sync postData: %s', $this->order->getIncrementId(), json_encode($postData)));
|
||
}
|
||
$res['response'] = $response;
|
||
} else {
|
||
$res['message'] = 'this order payment method is offline';
|
||
}
|
||
} catch (\Exception $exception) {
|
||
$res['message'] = $message = sprintf('customer deposit %s sync to Netsuite exception: ', $this->order->getIncrementId(), $exception->getMessage());
|
||
$this->output->writeln($message);
|
||
}
|
||
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* look for netsuite order id from http response header Location
|
||
* @param array $responseHeaders
|
||
* @return string
|
||
*/
|
||
protected function getNetsuiteOrderId(array $responseHeaders)
|
||
{
|
||
if (!empty($responseHeaders['Location'])) {
|
||
$isMatch = preg_match('/salesorder\/(\d+)/', $responseHeaders['Location'], $matches);
|
||
if ($isMatch) {
|
||
return $matches[1];
|
||
}
|
||
}
|
||
return '';
|
||
}
|
||
|
||
/**
|
||
*
|
||
*/
|
||
public function execute(InputInterface $input, OutputInterface $output): int
|
||
{
|
||
$this->input = $input;
|
||
$this->output = $output;
|
||
// $waitSyncOrders = $this->getWaitSyncOrders()->getItems();
|
||
//
|
||
// foreach ($waitSyncOrders as $order) {
|
||
// $this->order = $order;
|
||
// /* @var $order \Magento\Sales\Model\Order */
|
||
// try {
|
||
// $syncOrders = $this->getSyncOrders();
|
||
//
|
||
// $index = 1;
|
||
// $orderSyncSuccess = true;
|
||
// foreach ($syncOrders as $sourceCode => $syncOrder) {
|
||
// $locationId = $this->sources[$sourceCode]->getNetsuiteId();
|
||
// unset($syncOrder['increment_id']);
|
||
// $postData = $this->getPostData($locationId, array_values($syncOrder), $index);
|
||
//
|
||
// $syncOrders[$sourceCode]['increment_id'] = $postData['externalId'];
|
||
// $index++;
|
||
//
|
||
// try {
|
||
// $response = $this->netSuiteAPI->postData(self::NETSUITE_SALES_ORDER_SERVICE, $postData);
|
||
//
|
||
// if ($response['error'] != true){
|
||
// $syncOrders[$sourceCode]['netsuite_order_id'] = $this->getNetsuiteOrderId($this->netSuiteAPI->getResponseHeaders());
|
||
// $this->order->setIsNetsuiteSync(1);
|
||
// } else {
|
||
// $orderSyncSuccess = false;
|
||
// $message = sprintf('order %s sync to Netsuite fail', $postData['externalId']);
|
||
// $this->output->writeln($message);
|
||
// $this->output->writeln(sprintf('customer deposit %s sync response: %s', $this->order->getIncrementId(), json_encode($response)));
|
||
// $this->output->writeln(sprintf('customer deposit %s sync postData: %s', $this->order->getIncrementId(), json_encode($postData)));
|
||
// }
|
||
// } catch (InvalidArgumentException $e) {
|
||
// $message = sprintf('order %s sync to Netsuite crash fail: %s', $postData['externalId'], $e->getMessage());
|
||
// $this->output->writeln($message);
|
||
// }
|
||
//
|
||
// }
|
||
// $additionalInformation = ['syncOrders' => $syncOrders];
|
||
// if ($orderSyncSuccess) {
|
||
// $response = $this->customerDepositSync();
|
||
// $additionalInformation['depositSync'] = $response;
|
||
// }
|
||
//
|
||
// $this->order->setData('additional_information', json_encode($additionalInformation));
|
||
// $this->orderRepository->save($this->order);
|
||
// } catch (\Exception $exception) {
|
||
// $this->output->writeln('magento sync to netsuite exception: '.$exception->getMessage());
|
||
// $this->output->writeln('sync exception: '.json_encode($exception->getTrace()));
|
||
// }
|
||
// }
|
||
|
||
$product = $this->productRepository->getById(3657);
|
||
|
||
var_dump($product->getExtensionAttributes()->getNetsuiteId(), $product->getNetsuiteId());
|
||
return Command::SUCCESS;
|
||
}
|
||
} |