422 lines
14 KiB
PHP
Executable File
422 lines
14 KiB
PHP
Executable File
<?php
|
|
namespace JR\NetSuite\Service;
|
|
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\User\Model\User;
|
|
use Magento\User\Model\ResourceModel\User\CollectionFactory as UserCollectionFactory;
|
|
use Mirasvit\Rma\Model\ResourceModel\Address\CollectionFactory as AddressCollectionFactory;
|
|
use Mirasvit\Rma\Model\ResourceModel\Rma\CollectionFactory as RmaCollectionFactory;
|
|
use Mirasvit\Rma\Model\ResourceModel\Condition\CollectionFactory as ConditionCollectionFactory;
|
|
use Mirasvit\Rma\Model\ResourceModel\Reason\CollectionFactory as ReasonCollectionFactory;
|
|
use Mirasvit\Rma\Model\ResourceModel\Resolution\CollectionFactory as ResolutionCollectionFactory;
|
|
use Mirasvit\Rma\Model\AddressFactory;
|
|
use Mirasvit\Rma\Api\Repository\AddressRepositoryInterface;
|
|
use \Mirasvit\Rma\Api\Repository\RmaRepositoryInterface;
|
|
use Mirasvit\Rma\Api\Repository\StatusRepositoryInterface;
|
|
use \Mirasvit\Rma\Api\Service\Rma\RmaManagementInterface;
|
|
use Mirasvit\Rma\Controller\Adminhtml\Rma\Save as RmaSave;
|
|
use Magento\Framework\App\RequestInterface;
|
|
use Magento\Framework\Message\ManagerInterface;
|
|
use \Mirasvit\Rma\Api\Service\Performer\PerformerFactoryInterface;
|
|
use Mirasvit\Rma\Api\Service\Rma\RmaManagement\SaveInterface;
|
|
use \Mirasvit\Rma\Controller\Adminhtml\Rma\PostDataProcessor;
|
|
|
|
use JR\NetSuite\Model\ResourceModel\Location\CollectionFactory as LocationCollectionFactory;
|
|
use JR\NetSuite\Mapper\RmaMapper;
|
|
use JR\NetSuite\Mapper\orderMapper;
|
|
use JR\NetSuite\Logger\Logger;
|
|
|
|
class RmaSyncService
|
|
{
|
|
const TAX_GROUP = 'TaxGroup';
|
|
const SHIP_ITEM = 'ShipItem';
|
|
const INVT_PART = 'InvtPart';
|
|
const DISCOUNT = 'Discount';
|
|
|
|
const REASON_MAP = [
|
|
'3' => 'S-Internal Error', // sales made mistake
|
|
'4' => 'DOA',
|
|
'5' => 'Customer Cancellation',
|
|
'6' => 'Manufacture Defect',
|
|
];
|
|
|
|
const CONDITION_MAP = [
|
|
'2' => 'Wrong Merchandise Received',
|
|
'6' => 'Product Defective',
|
|
'11' => 'No Longer Needed/Return as New',
|
|
'13' => 'Others',
|
|
];
|
|
|
|
const RESOLUTION_MAP = [
|
|
'1' => 'AR with Return',
|
|
'2' => 'Replacement',
|
|
'3' => 'Refund',
|
|
'4' => 'Credit',
|
|
'5' => 'AR without Return',
|
|
'6' => 'Substitute',
|
|
];
|
|
|
|
/**
|
|
* @var RmaCollectionFactory
|
|
*/
|
|
protected $rmaCollectionFactory;
|
|
|
|
/**
|
|
* @var RmaRepositoryInterface
|
|
*/
|
|
protected $rmaRepository;
|
|
|
|
/**
|
|
* @var StatusRepositoryInterface
|
|
*/
|
|
protected $statusRepository;
|
|
|
|
/**
|
|
* @var RmaManagementInterface
|
|
*/
|
|
protected $rmaManagement;
|
|
|
|
/**
|
|
* @var RmaSave
|
|
*/
|
|
protected $rmaSave;
|
|
|
|
/**
|
|
* @var RequestInterface
|
|
*/
|
|
protected $request;
|
|
|
|
/**
|
|
* @var ManagerInterface
|
|
*/
|
|
protected $messageManager;
|
|
|
|
/**
|
|
* @var PerformerFactoryInterface
|
|
*/
|
|
private $performer;
|
|
|
|
/**
|
|
* @var SaveInterface
|
|
*/
|
|
private $rmaSaveService;
|
|
|
|
/**
|
|
* @var PostDataProcessor
|
|
*/
|
|
private $dataProcessor;
|
|
|
|
/**
|
|
* @var UserCollectionFactory
|
|
*/
|
|
protected $userCollectionFactory;
|
|
|
|
/**
|
|
* @var RmaMapper
|
|
*/
|
|
protected $rmaMapper;
|
|
|
|
/**
|
|
* @var OrderMapper
|
|
*/
|
|
protected $orderMapper;
|
|
|
|
/**
|
|
* @var Logger
|
|
*/
|
|
protected $logger;
|
|
|
|
/**
|
|
* @var \Mirasvit\Rma\Model\ResourceModel\Condition\CollectionFactory
|
|
*/
|
|
private $conditionCollectionFactory;
|
|
|
|
/**
|
|
* @var \Mirasvit\Rma\Model\ResourceModel\Reason\CollectionFactory
|
|
*/
|
|
private $ReasonCollectionFactory;
|
|
|
|
/**
|
|
* @var \Mirasvit\Rma\Model\ResourceModel\Resolution\CollectionFactory
|
|
*/
|
|
private $resolutionCollectionFactory;
|
|
|
|
/**
|
|
* @var \JR\NetSuite\Model\ResourceModel\Location\CollectionFactory
|
|
*/
|
|
private $locationCollectionFactory;
|
|
|
|
/**
|
|
* @var \Mirasvit\Rma\Model\ResourceModel\Address\CollectinFatory
|
|
*/
|
|
private $AddressCollectionFactory;
|
|
|
|
/**
|
|
* @var \Mirasvit\Rma\Model\AddressFactory
|
|
*/
|
|
private $addressFactory;
|
|
|
|
/**
|
|
* @var \Mirasvit\Rma\Api\Repository\AddressRepositoryInterface
|
|
*/
|
|
private $addressRepository;
|
|
|
|
/**
|
|
* @var \Magento\Customer\Api\CustomerRepositoryInterface
|
|
*/
|
|
private $customerRepository;
|
|
|
|
/**
|
|
* @var \Magento\Framework\Registry
|
|
*/
|
|
private $registry;
|
|
|
|
public function __construct(
|
|
RmaCollectionFactory $rmaCollectionFactory,
|
|
RmaRepositoryInterface $rmaRepository,
|
|
StatusRepositoryInterface $statusRepository,
|
|
RmaManagementInterface $rmaManagement,
|
|
RmaSave $rmaSave,
|
|
RequestInterface $request,
|
|
ManagerInterface $messageManager,
|
|
PerformerFactoryInterface $performer,
|
|
SaveInterface $rmaSaveService,
|
|
PostDataProcessor $dataProcessor,
|
|
UserCollectionFactory $userCollectionFactory,
|
|
ConditionCollectionFactory $conditionCollectionFactory,
|
|
ReasonCollectionFactory $ReasonCollectionFactory,
|
|
ResolutionCollectionFactory $resolutionCollectionFactory,
|
|
RmaMapper $rmaMapper,
|
|
OrderMapper $orderMapper,
|
|
LocationCollectionFactory $locationCollectionFactory,
|
|
AddressCollectionFactory $AddressCollectionFactory,
|
|
AddressFactory $addressFactory,
|
|
AddressRepositoryInterface $addressRepository,
|
|
Logger $logger,
|
|
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
|
|
\Magento\Framework\Registry $registry
|
|
) {
|
|
$this->rmaCollectionFactory = $rmaCollectionFactory;
|
|
$this->rmaRepository = $rmaRepository;
|
|
$this->statusRepository = $statusRepository;
|
|
$this->rmaManagement = $rmaManagement;
|
|
$this->rmaSave = $rmaSave;
|
|
$this->request = $request;
|
|
$this->messageManager = $messageManager;
|
|
$this->performer = $performer;
|
|
$this->rmaSaveService = $rmaSaveService;
|
|
$this->dataProcessor = $dataProcessor;
|
|
$this->userCollectionFactory = $userCollectionFactory;
|
|
$this->rmaMapper = $rmaMapper;
|
|
$this->orderMapper = $orderMapper;
|
|
$this->logger = $logger;
|
|
$this->customerRepository = $customerRepository;
|
|
$this->registry = $registry;
|
|
$this->addressRepository = $addressRepository;
|
|
$this->addressFactory = $addressFactory;
|
|
$this->AddressCollectionFactory = $AddressCollectionFactory;
|
|
$this->locationCollectionFactory = $locationCollectionFactory;
|
|
$this->resolutionCollectionFactory = $resolutionCollectionFactory;
|
|
$this->ReasonCollectionFactory = $ReasonCollectionFactory;
|
|
$this->conditionCollectionFactory = $conditionCollectionFactory;
|
|
}
|
|
|
|
public function updateRmaStatus($data) {
|
|
if (empty($data)) {
|
|
return;
|
|
}
|
|
// update RMA status
|
|
$rmas = $this->rmaCollectionFactory->create();
|
|
$rmas->addFieldToFilter('rma_id', array('in' => array_keys($data)));
|
|
foreach ($rmas as $rma) {
|
|
$code = strtolower($data[$rma->getRmaId()]);
|
|
$status = $this->statusRepository->getByCode($code);
|
|
if (!$status?->getId()) {
|
|
continue;
|
|
}
|
|
$rma->setStatusId($status->getId());
|
|
$rma->save();
|
|
}
|
|
}
|
|
|
|
|
|
public function createInNetSuite($rmaId) {
|
|
$rma = $this->rmaRepository->get($rmaId);
|
|
$order = $this->rmaManagement->getOrder($rma);
|
|
$customer = $this->rmaManagement->getCustomer($rma);
|
|
$rmaData = $this->rmaMapper->convertToNetSuiteFormat($rma, $order, $customer);
|
|
}
|
|
|
|
public function getOrder($data) {
|
|
if (empty($data['netsuite_order_id']) && empty($data['netsuite_order_number'])) {
|
|
throw new \Exception('Skipped: Netsuite order not found.');
|
|
}
|
|
|
|
if (!empty($data['netsuite_order_id'])) {
|
|
$order = $this->orderMapper->getOrderBy('netsuite_id', $data['netsuite_order_id']);
|
|
}
|
|
|
|
if (!isset($order) && !empty($data['netsuite_order_number'])) {
|
|
$netsuiteNumber = 'SO' . str_pad(ltrim($data['netsuite_order_number'], '#SOso0'), 7, '0', STR_PAD_LEFT);
|
|
$order = $this->orderMapper->getOrderBy('netsuite_number', $netsuiteNumber);
|
|
}
|
|
|
|
if (!$order) {
|
|
throw new \Exception('Skipped: Netsuite order not sync.');
|
|
}
|
|
|
|
return $order;
|
|
}
|
|
|
|
public function createOrSkip($data, $order = null) {
|
|
// if (!isset($data['customer']['email']) || empty($data['customer']['email'])) {
|
|
// throw new \Exception('Skipped: Customer email not found.');
|
|
// }
|
|
|
|
// // found customer id by email
|
|
// $customer = $this->customerRepository->get($data['customer']['email']);
|
|
// if (!$customer) {
|
|
// // retrun error
|
|
// throw new \Exception('Skipped: Customer not found.');
|
|
// }
|
|
|
|
if (!$order) $order = $this->getOrder($data);
|
|
|
|
// if ($order->getCustomerEmail() != $data['customer']['email']) {
|
|
// throw new \Exception('Skipped: Customer email not match.');
|
|
// }
|
|
|
|
// if billing zipcode not match
|
|
// if (isset($data['customer']['billing_address']['postcode']) && $order->getBillingAddress()->getPostcode() != $data['customer']['billing_address']['postcode']) {
|
|
// throw new \Exception('Skipped: Billing zipcode not match.');
|
|
// }
|
|
|
|
// get all condition and reason
|
|
$conditions = $this->conditionCollectionFactory->create();
|
|
$reasons = $this->ReasonCollectionFactory->create();
|
|
$resolution = $this->resolutionCollectionFactory->create();
|
|
$conditionMap = [];
|
|
$reasonMap = [];
|
|
$resolutionMap = [];
|
|
foreach ($conditions as $condition) {
|
|
$conditionMap[$condition->getName()] = $condition->getId();
|
|
}
|
|
foreach ($reasons as $reason) {
|
|
$reasonMap[$reason->getName()] = $reason->getId();
|
|
}
|
|
foreach ($resolution as $res) {
|
|
$resolutionMap[$res->getName()] = $res->getId();
|
|
}
|
|
|
|
// get all order items
|
|
$orderItems = $order->getAllItems();
|
|
$filteredOrderItems = [];
|
|
$skuMap = array_column($data['items'], 'sku');
|
|
foreach ($orderItems as $orderItem) {
|
|
if (in_array($orderItem->getSku(), $skuMap)) {
|
|
$filteredOrderItems[$orderItem->getSku()] = $orderItem->getId();
|
|
}
|
|
}
|
|
|
|
$items = [];
|
|
foreach ($data['items'] as $item) {
|
|
if ($item['type'] != self::INVT_PART) {
|
|
continue;
|
|
}
|
|
$items[] = [
|
|
'order_id' => $order->getId(),
|
|
'order_item_id' => $filteredOrderItems[$item['sku']],
|
|
'product_sku' => $item['sku'],
|
|
'qty_requested' => abs($item['qty']),
|
|
'reason_id' => $item['reason'] != '' ? $reasonMap[self::REASON_MAP[$item['reason']]] : '',
|
|
'condition_id' => $item['condition'] != '' ? $conditionMap[self::CONDITION_MAP[$item['condition']]] : '',
|
|
'resolution_id' => $item['resolution'] != '' ? $resolutionMap[self::RESOLUTION_MAP[$item['resolution']]] : '',
|
|
];
|
|
}
|
|
|
|
$status = $this->statusRepository->getByCode($data['status']);
|
|
|
|
// filter location by loction id and get the name
|
|
$location = $this->locationCollectionFactory->create()->addFieldToFilter('location_id', $data['location'])->getFirstItem();
|
|
|
|
if (!$location) {
|
|
throw new \Exception('Skipped: Location not found.');
|
|
}
|
|
|
|
// find the return address
|
|
$address = $this->AddressCollectionFactory->create()->addFieldToFilter('name', $location->getName())->getFirstItem();
|
|
if (!$address) {
|
|
// add the address to the address table by get the repository
|
|
$address = $this->addressFactory->create();
|
|
$address->addData([
|
|
'is_active' => 1,
|
|
'address' => $location->getAddress(),
|
|
'name' => $location->getName(),
|
|
]);
|
|
$address = $this->addressRepository->save($address);
|
|
}
|
|
|
|
$params = [
|
|
'order_id' => $order->getId(),
|
|
'user_id' => 0,
|
|
'status_id' => $status->getId(),
|
|
'is_resolved' => in_array($data['status'], ['refunded', 'closed', 'cancelled']),
|
|
'return_address' => $address->getId(),
|
|
'first_name' => $data['customer']['firstname'],
|
|
'last_name' => $data['customer']['lastname'],
|
|
'company' => $data['customer']['company_name'],
|
|
'email' => $order->getCustomerEmail(),
|
|
'phone' => $data['customer']['shipping_address']['telephone'],
|
|
'street' => $data['customer']['shipping_address']['street'][0],
|
|
'street2' => $data['customer']['shipping_address']['street'][1],
|
|
'city' => $data['customer']['shipping_address']['city'],
|
|
'postcode' => $data['customer']['shipping_address']['postcode'],
|
|
'items' => $items,
|
|
];
|
|
|
|
// unset current_rma registry
|
|
$this->registry->unregister('current_rma');
|
|
$user = $this->userCollectionFactory->create()->getFirstItem();
|
|
$performer = $this->performer->create(PerformerFactoryInterface::USER, $user);
|
|
$rma = $this->rmaSaveService->saveRma(
|
|
$performer,
|
|
$this->dataProcessor->filterRmaData($params),
|
|
$this->dataProcessor->filterRmaItems($params)
|
|
);
|
|
|
|
// save created at time to rma
|
|
$createdAt = \DateTime::createFromFormat('m/d/Y g:i a', $data['recorded_at'], new \DateTimeZone('America/Los_Angeles'));
|
|
$createdAt->setTimezone(new \DateTimeZone('UTC'));
|
|
$rma->setCreatedAt($createdAt->format('Y-m-d H:i:s'));
|
|
$rma->save();
|
|
|
|
return [
|
|
'data' => $rma,
|
|
'is_new' => true
|
|
];
|
|
|
|
}
|
|
|
|
public function update($data, $rmaId) {
|
|
if (empty($data['status'])) {
|
|
throw new \Exception('Skipped: Status not found.');
|
|
}
|
|
|
|
$rma = $this->rmaRepository->get($rmaId);
|
|
|
|
$status = $this->statusRepository->getByCode($data['status']);
|
|
if (!$status) {
|
|
throw new \Exception('Skipped: Status not found.');
|
|
}
|
|
|
|
$rma->setStatusId($status->getId());
|
|
$rma->save();
|
|
|
|
return [
|
|
'data' => $rma,
|
|
'is_new' => false
|
|
];
|
|
}
|
|
|
|
}
|