491 lines
16 KiB
PHP
Executable File
491 lines
16 KiB
PHP
Executable File
<?php
|
|
|
|
namespace JR\NetSuite\Mapper;
|
|
|
|
use JR\NetSuite\Mapper\AbstractMapper;
|
|
use Magento\Directory\Model\RegionFactory;
|
|
use Magento\Customer\Api\GroupRepositoryInterface;
|
|
use Magento\Framework\Api\SearchCriteriaBuilder;
|
|
use Magento\Framework\Exception\NoSuchEntityException;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\Customer\Api\CustomerRepositoryInterface;
|
|
use Magento\Customer\Api\Data\CustomerInterfaceFactory;
|
|
use Magento\Customer\Api\Data\AddressInterfaceFactory;
|
|
use Magento\Sales\Api\Data\OrderInterface;
|
|
use Magento\Framework\Event\ManagerInterface as EventManager;
|
|
use Magento\Store\Model\StoreManagerInterface;
|
|
use Magento\Directory\Model\CountryFactory;
|
|
|
|
// Handles the specifics of mapping product data.
|
|
class CustomerMapper {
|
|
|
|
const STATUSES = [
|
|
'13' => 'Customer-Active',
|
|
'21' => 'Customer-Bad Debt',
|
|
'20' => 'Customer-Blacklist',
|
|
'22' => 'Customer-Fraudulent',
|
|
'15' => 'Customer-Inactive',
|
|
'23' => 'Customer-New',
|
|
'17' => 'Lead-Free',
|
|
'6' => 'Lead-New',
|
|
'18' => 'Lead-Pending Approval',
|
|
'7' => 'Lead-Unqualified',
|
|
'8' => 'Prospect-In Discussion',
|
|
'10' => 'Prospect-Proposal',
|
|
];
|
|
|
|
/**
|
|
* customer group
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $default_customer_group;
|
|
|
|
/**
|
|
* helper
|
|
*
|
|
* @var \JR\NetSuite\Helper\Data
|
|
*/
|
|
protected $helper;
|
|
|
|
/**
|
|
* array to store customer group id.
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $customerGroupIdMap = [];
|
|
|
|
/**
|
|
* @var RegionFactory
|
|
*/
|
|
protected $regionFactory;
|
|
|
|
/**
|
|
* @var \Magento\Customer\Model\GroupFactory
|
|
*/
|
|
protected $customerGroupFactory;
|
|
|
|
/**
|
|
* @var GroupRepositoryInterface
|
|
*/
|
|
protected $groupRepository;
|
|
|
|
/**
|
|
* @var SearchCriteriaBuilder
|
|
*/
|
|
protected $searchCriteriaBuilder;
|
|
|
|
/**
|
|
* @var CustomerRepositoryInterface
|
|
*/
|
|
protected $customerRepository;
|
|
|
|
/**
|
|
* @var CustomerInterfaceFactory
|
|
*/
|
|
protected $customerFactory;
|
|
|
|
/**
|
|
* @var AddressInterfaceFactory
|
|
*/
|
|
protected $addressFactory;
|
|
|
|
/**
|
|
* @var EventManager
|
|
*/
|
|
protected $eventManager;
|
|
|
|
/**
|
|
* @var StoreManagerInterface
|
|
*/
|
|
protected $storeManager;
|
|
|
|
/**
|
|
* @var CountryFactory
|
|
*/
|
|
protected $countryFactory;
|
|
|
|
/**
|
|
* CustomerMapper constructor.
|
|
*/
|
|
public function __construct(
|
|
RegionFactory $regionFactory,
|
|
\Magento\Customer\Model\GroupFactory $customerGroupFactory,
|
|
GroupRepositoryInterface $groupRepository,
|
|
SearchCriteriaBuilder $searchCriteriaBuilder,
|
|
\JR\NetSuite\Helper\Data $helper,
|
|
CustomerRepositoryInterface $customerRepository,
|
|
CustomerInterfaceFactory $customerFactory,
|
|
AddressInterfaceFactory $addressFactory,
|
|
EventManager $eventManager,
|
|
StoreManagerInterface $storeManager,
|
|
CountryFactory $countryFactory
|
|
) {
|
|
$this->regionFactory = $regionFactory;
|
|
$this->customerGroupFactory = $customerGroupFactory;
|
|
$this->groupRepository = $groupRepository;
|
|
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
|
|
$this->helper = $helper;
|
|
$this->default_customer_group = $this->helper->getDefaultCustomerGroup();
|
|
$this->customerRepository = $customerRepository;
|
|
$this->customerFactory = $customerFactory;
|
|
$this->addressFactory = $addressFactory;
|
|
$this->eventManager = $eventManager;
|
|
$this->storeManager = $storeManager;
|
|
$this->countryFactory = $countryFactory;
|
|
}
|
|
|
|
/**
|
|
* Convert data from NetSuite format to Magento format.
|
|
*
|
|
* @param array $netSuiteData
|
|
* @return array
|
|
*/
|
|
public function convertToMagentoFormat($netSuiteData) {
|
|
/*
|
|
[internalid] => 246911
|
|
[isinactive] =>
|
|
[entityid] => 08/03NJ-MET-NC
|
|
[entitystatus] => 8
|
|
[addressee] => Modern Edge Technologies
|
|
[addressphone] => (336) 699-2158
|
|
[email] => babbott@modernedgetechnology.com
|
|
[phone] => (336) 699-2158
|
|
[balance] => .00
|
|
[creditlimit] => 1.00
|
|
[billattention] => Black Abbott
|
|
[billaddress1] => 6629 Old U.S. 421
|
|
[billaddress2] =>
|
|
[billaddressee] => Modern Edge Technologies
|
|
[billcity] => East Bend
|
|
[billcountry] => US
|
|
[billstate] => NC
|
|
[billzipcode] => 27018
|
|
[isdefaultbilling] => 1
|
|
[isperson] =>
|
|
[firstname] =>
|
|
[lastname] =>
|
|
[companyname] => Modern Edge Technologies
|
|
[shipaddress1] => 6629 Old U.S. 421
|
|
[shipaddress2] =>
|
|
[shipaddressee] => Modern Edge Technologies
|
|
[shipattention] => Black Abbott
|
|
[shipcity] => East Bend
|
|
[shipcomplete] =>
|
|
[shipcountry] => US
|
|
[shippingcarrier] =>
|
|
[shipstate] => NC
|
|
[shipzip] => 27018
|
|
[isdefaultshipping] => 1
|
|
*/
|
|
// echo json_encode($netSuiteData, JSON_PRETTY_PRINT) . "\n";
|
|
// convert netsuite data to magento data
|
|
$magentoData = [];
|
|
foreach ($netSuiteData as $data) {
|
|
$name = $this->filterFirstNonEmpty([
|
|
$data['shipattention'] ?? '',
|
|
$data['billattention'] ?? '',
|
|
$data['addressee'] ?? '',
|
|
$data['companyname'],
|
|
]);
|
|
$convertedData = [
|
|
'is_active' => $data['isinactive'] ? 0 : 1,
|
|
'netsuite_entity_id' => $data['entityid'],
|
|
'netsuite_customer_id' => $data['internalid'],
|
|
'status' => self::STATUSES[$data['entitystatus']],
|
|
'firstname' => count($name) > 0 ? array_shift($name) : $this->replaceName($data['companyname']),
|
|
'lastname' => count($name) > 0 ? (empty(implode(' ', $name)) ? $this->replaceName($data['companyname']) : implode(' ', $name)) : $this->replaceName($data['companyname']),
|
|
'email' => $data['email'],
|
|
'company_name' => $data['companyname'],
|
|
'phone' => $data['phone'],
|
|
'group_id' => $this->getDefaultCustomerGroupId(),
|
|
'reporting_office' => $data['cseg_ncg_rep_office'],
|
|
'isdefaultshipping' => $data['isdefaultshipping'],
|
|
'isdefaultbilling' => $data['isdefaultbilling'],
|
|
];
|
|
|
|
$shipaddressee = $this->filterFirstNonEmpty([
|
|
$data['shipattention'],
|
|
$data['shipaddressee'],
|
|
$data['billattention'] ?? '',
|
|
]);
|
|
if (empty($shipaddressee)) {
|
|
$shipaddressee = $this->getNameFromAddressText($data['shipaddress']);
|
|
}
|
|
$convertedData['shipping_address'] = [
|
|
'firstname' => count($shipaddressee) > 0 ? array_shift($shipaddressee) : '',
|
|
'lastname' => count($shipaddressee) > 0 ? implode(' ', $shipaddressee) : $data['companyname'],
|
|
'company' => $data['companyname'],
|
|
'street' => $data['shipaddress1'] != '' ?
|
|
[$data['shipaddress1'], $data['shipaddress2']] :
|
|
[$data['billaddress1'], $data['billaddress2']],
|
|
'city' => $data['shipcity'],
|
|
'country_id' => $data['shipcountry'],
|
|
// 'region' => $data['shipstate'],
|
|
'region_id' => $this->getRegion($data['shipcountry'], $data['shipstate'])->getId(),
|
|
'postcode' => $data['shipzip'],
|
|
'telephone' => $data['addressphone'] == '' ? $data['phone'] : $data['addressphone'],
|
|
];
|
|
|
|
$billaddressee = $this->filterFirstNonEmpty([
|
|
$data['billattention'],
|
|
$data['billaddressee'],
|
|
$data['shipattention'] ?? '',
|
|
]);
|
|
if (empty($billaddressee)) {
|
|
$billaddressee = $this->getNameFromAddressText($data['billaddress']);
|
|
}
|
|
$convertedData['billing_address'] = [
|
|
'firstname' => count($billaddressee) > 0 ? array_shift($billaddressee) : '',
|
|
'lastname' => count($billaddressee) > 0 ?
|
|
(empty(implode(' ', $billaddressee)) ? $data['companyname'] : implode(' ', $billaddressee)) : $data['companyname'],
|
|
'company' => $data['companyname'],
|
|
'street' => [$data['billaddress1'], $data['billaddress2']],
|
|
'city' => $data['billcity'],
|
|
'country_id' => $data['billcountry'],
|
|
// 'region' => $data['billstate'],
|
|
'region_id' => $this->getRegion($data['billcountry'], $data['billstate'])->getId(),
|
|
'postcode' => $data['billzipcode'],
|
|
'telephone' => $data['addressphone'] == '' ? $data['phone'] : $data['addressphone'],
|
|
];
|
|
|
|
// 'phone' => $data['phone'],
|
|
// 'fax' => $data['fax'],
|
|
// 'website' => $data['url'],
|
|
// 'street' => $data['address1'],
|
|
// 'city' => $data['city'],
|
|
// 'country_id' => $data['country'],
|
|
// 'region' => $data['state'],
|
|
// 'postcode' => $data['zip'],
|
|
// 'created_at' => $data['createddate'],
|
|
// 'updated_at' => $data['lastmodifieddate']
|
|
$magentoData[] = $convertedData;
|
|
}
|
|
return $magentoData;
|
|
}
|
|
|
|
/**
|
|
* Convert data from Magento format to NetSuite format.
|
|
*
|
|
* @param array $magentoData
|
|
* @return array
|
|
*/
|
|
public function convertToNetSuiteFormat($magentoData) {
|
|
// Your conversion logic here
|
|
}
|
|
|
|
/**
|
|
* convert magento customer to netsuite format by email
|
|
*/
|
|
public function convertToNetSuiteFormatByEmail($email) {
|
|
$customer = $this->customerRepository->get($email);
|
|
$phone = $customer->getCustomAttribute('phone')?->getValue();
|
|
$company = $customer->getCustomAttribute('company')?->getValue();
|
|
|
|
$defaultBillingAddressId = $customer->getDefaultBilling() ?? null;
|
|
$defaultShippingAddressId = $customer->getDefaultShipping() ?? null;
|
|
|
|
$netsuiteAddressList = [];
|
|
|
|
$addresses = $customer->getAddresses();
|
|
foreach ($addresses as $address) {
|
|
$netsuiteAddress = new \stdClass(); // Assuming stdClass for simplicity, replace with actual class if applicable
|
|
|
|
$netsuiteAddress->attention = $customer->getFirstname() . ' ' . $customer->getLastname();
|
|
|
|
$street = array_filter($address->getStreet());
|
|
if (count($street) == 1) {
|
|
$street = explode(",", $street[0]);
|
|
if (count($street) > 2) {
|
|
$street1 = trim(implode(",", array_slice($street, 0, count($street) - 1)));
|
|
} else {
|
|
$street1 = trim($street[0]);
|
|
}
|
|
if (count($street) > 1) {
|
|
$street2 = trim($street[count($street) - 1]);
|
|
}
|
|
}
|
|
$netsuiteAddress->addr1 = $street1 ?? '';
|
|
$netsuiteAddress->addr2 = $street2 ?? '';
|
|
$netsuiteAddress->city = $address->getCity() ?? '';
|
|
$netsuiteAddress->zip = $address->getPostcode() ?? '';
|
|
$netsuiteAddress->state = $address->getRegion()?->getRegionCode() ?? '';
|
|
$netsuiteAddress->country = $address->getCountryId() ?? '';
|
|
|
|
$phone = $phone ?? $address->getTelephone();
|
|
$company = $company ?? $address->getCompany();
|
|
|
|
// Dispatch event or additional processing
|
|
// $this->eventManager->dispatch('netsuite_address_create_before', ['netsuite_address' => $netsuiteAddress]);
|
|
|
|
$netsuiteAddressList[] = [
|
|
'defaultbilling' => $address->getId() == $defaultBillingAddressId,
|
|
'defaultshipping' => $address->getId() == $defaultShippingAddressId,
|
|
'address' => $netsuiteAddress,
|
|
];
|
|
}
|
|
|
|
if (!empty($phone)) {
|
|
$phone = preg_replace('/[^0-9]/', '', $phone);
|
|
if (strlen($phone) == 10) {
|
|
$phone = '0001' . $phone;
|
|
}
|
|
$phone = str_pad($phone, 14, '0', STR_PAD_LEFT);
|
|
}
|
|
|
|
$netsuiteCustomer = [
|
|
//"requestTime": 40780772495802300,
|
|
'requestTime' => time(),
|
|
'firstName' => $customer->getFirstname(),
|
|
'lastName' => $customer->getLastname(),
|
|
'addressBooks' => $netsuiteAddressList,
|
|
'isPerson' => "T",
|
|
'phone' => $phone ?? '',
|
|
'companyname' => $company ?? '',
|
|
'custentity_source' => 3,
|
|
'entityid' => 'magento_' . $customer->getId(),
|
|
'leadsource' => -6,
|
|
'title' => $customer->getPrefix() ?? '',
|
|
'email' => $customer->getEmail(),
|
|
];
|
|
|
|
return $netsuiteCustomer;
|
|
}
|
|
|
|
/**
|
|
* Convert data to NetSuite format by order
|
|
*
|
|
* @param OrderInterface $order
|
|
* @return array
|
|
*/
|
|
public function convertToNetSuiteFormatByOrder(OrderInterface $order) {
|
|
if ($customerData = $this->convertToNetSuiteFormatByEmail($order->getCustomerEmail())) {
|
|
return $customerData;
|
|
}
|
|
|
|
$customer = $this->customerFactory->create();
|
|
$customer->setEmail($order->getCustomerEmail())
|
|
->setFirstname($order->getCustomerFirstname())
|
|
->setLastname($order->getCustomerLastname() ?: $order->getCustomerFirstname())
|
|
->setMiddlename($order->getCustomerMiddlename())
|
|
->setStoreId($order->getStoreId());
|
|
|
|
// Assuming setPrimaryBillingAddress() and setPrimaryShippingAddress() logic is handled separately,
|
|
// as Magento 2 uses addresses linked to customer entities differently than Magento 1
|
|
|
|
// Add customer addresses
|
|
$billingAddress = $this->addressFactory->create()->setData($order->getBillingAddress()->getData());
|
|
$shippingAddress = $this->addressFactory->create()->setData($order->getShippingAddress()->getData());
|
|
|
|
$customer->setAddresses([$billingAddress, $shippingAddress]);
|
|
|
|
// Convert to Netsuite format and send to Netsuite
|
|
// Assuming getNetsuiteFormat is an available method that transforms Magento customer to Netsuite format
|
|
$netsuiteCustomer = $this->getNetsuiteFormat($customer);
|
|
|
|
if ($netsuiteCustomer->externalId == 0) {
|
|
$netsuiteCustomer->externalId = null;
|
|
}
|
|
|
|
// Dispatch event before sending customer to Netsuite
|
|
$this->eventManager->dispatch(
|
|
'netsuite_customer_send_before',
|
|
['netsuite_customer' => $netsuiteCustomer]
|
|
);
|
|
|
|
// Send the customer to Netsuite
|
|
// Assuming _getNetsuiteService() and the subsequent Netsuite call are implemented
|
|
$response = $this->_getNetsuiteService()->add($netsuiteCustomer);
|
|
|
|
if ($response->writeResponse->status->isSuccess) {
|
|
return $response->writeResponse->baseRef->internalId;
|
|
} else {
|
|
throw new Exception(json_encode($response->writeResponse->status->statusDetail));
|
|
}
|
|
}
|
|
|
|
protected function replaceName($value) {
|
|
return preg_replace('/[^\p{L}\p{M}\,\-\_\.\'\s\d]/', ' ', $value);
|
|
}
|
|
|
|
/**
|
|
* filter first non-empty value from array and return as array.
|
|
*
|
|
* @param array $array
|
|
* @return array
|
|
*/
|
|
protected function filterFirstNonEmpty($array) {
|
|
foreach ($array as $value) {
|
|
if ($value != '') {
|
|
$value = $this->replaceName($value);
|
|
$value = explode(' ', $value);
|
|
return $value;
|
|
}
|
|
}
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Get name from address text.
|
|
*
|
|
* @param string $address
|
|
* @return array
|
|
*/
|
|
protected function getNameFromAddressText($address) {
|
|
if (empty($address)) {
|
|
return [];
|
|
}
|
|
return $this->filterFirstNonEmpty(explode("\n", $address));
|
|
}
|
|
|
|
/**
|
|
* Get customer group ID by name.
|
|
*
|
|
* @param string $name
|
|
* @return int
|
|
*/
|
|
protected function getCustomerGroupIdByName($name) {
|
|
$searchCriteria = $this->searchCriteriaBuilder
|
|
->addFilter('customer_group_code', $name)
|
|
->create();
|
|
try {
|
|
$customerGroup = $this->groupRepository->getList($searchCriteria)->getItems();
|
|
return array_shift($customerGroup)->getId();
|
|
} catch (NoSuchEntityException $e) {
|
|
throw new LocalizedException(__("Error fetching customer group ID: %1", $e->getMessage()));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* get wholesale customer group id.
|
|
*
|
|
* @return int
|
|
*/
|
|
protected function getDefaultCustomerGroupId() {
|
|
if (!isset($this->customerGroupIdMap[$this->default_customer_group])) {
|
|
$this->customerGroupIdMap[$this->default_customer_group] = $this->getCustomerGroupIdByName($this->default_customer_group);
|
|
}
|
|
return $this->customerGroupIdMap[$this->default_customer_group];
|
|
}
|
|
|
|
/**
|
|
* Get region by country code and region code.
|
|
*
|
|
* @param string $countryCode
|
|
* @param string $regionCode
|
|
* @return \Magento\Directory\Model\Region
|
|
|
|
*/
|
|
protected function getRegion($countryCode, $regionCode) {
|
|
try {
|
|
$region = $this->regionFactory->create();
|
|
$region->loadByCode($regionCode, $countryCode);
|
|
return $region ?? '';
|
|
} catch (\Exception $e) {
|
|
throw new LocalizedException(__("Error fetching region ID: %1", $e->getMessage()));
|
|
}
|
|
}
|
|
|
|
}
|
|
|