Files

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
];
}
}