<?php
namespace App\Controller;
use App\Entity\Autoresponder;
use App\Entity\AutoResponderLog;
use App\Entity\Comm;
use App\Entity\Customer;
use App\Factory\MailerFactory;
use App\Utils\BigCommerceClient;
use App\Utils\BigCommerceConfig;
use App\Utils\WebhookManager;
use App\Utils\SalesforceConfig;
use Psr\Log\LoggerInterface;
use Bigcommerce\Api\Client as Bigcommerce;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use App\Repository\SalesAgentRepository;
use App\Repository\MarketSegmentRepository;
use App\Repository\CustomerGroupRepository;
use Symfony\Component\HttpFoundation\Response;
use App\Entity\SalesAgent;
use App\Entity\MarketSegment;
use App\Entity\CustomerGroup;
use Symfony\Component\HttpFoundation\RedirectResponse;
use App\Utils\bjsmasth\salesforce_api\CRUD;
use App\Service\Customer\SalesForce\ConverterInterface as SFField;
class SalesforceController extends AbstractController
{
const ACTION_ADD_ORDER_WEBHOOK = 'order_add_webhook';
const ACTION_RECREATE_ORDER_WEBHOOK = 'order_recreate_webhook';
const DT_FORMAT = \DateTime::ISO8601;
public $module_name = 'salesforce';
public function product_discount($parent_id, $products,$product_options_array)
{
$total_price = 0;
foreach ($products as $product)
{
if ($product->parent_order_product_id == $parent_id)
{
$product_price = Bigcommerce::getProduct($product->product_id);
if (!is_null($product_options_array[$product->product_id]))
{
$qty=$product_options_array[$product->product_id];
$total_price = $total_price + ($product_price->price*$qty);
}
else {
$total_price = $total_price + ($product_price->price);
}
}
}
return $total_price;
}
public function index()
{
return $this->render('/salesforce/salesforce.html.twig');
}
public function Settings(WebhookManager $hook)
{
$twigGlobals = $this->container->get('twig')->getGlobals();
$orderAddHookInfo = $hook->getWebhookInfoForRender($twigGlobals['create_order_scope'], $this->module_name);
$orderUpdateHookInfo = $hook->getWebhookInfoForRender($twigGlobals['update_order_scope'], $this->module_name);
$orderStatusUpdateHookInfo = $hook->getWebhookInfoForRender($twigGlobals['update_order_status_scope'], $this->module_name);
$addHookDestination = $this->generateUrl('salesforce_hook_create', [],UrlGeneratorInterface::ABSOLUTE_URL);
$delHookDestination = $this->generateUrl('salesforce_hook_delete', [],UrlGeneratorInterface::ABSOLUTE_URL);
$webhooks = [
'order' => [
'order_add_hook' => [
'name' => 'Order create webhook',
'obj' => $orderAddHookInfo['obj'],
'scope' => $twigGlobals['create_order_scope'],
'aid' => 'order_add_webhook',
'last_webhook_received' => $orderAddHookInfo['lastTimeReceived'],
],
'order_update_hook' => [
'name' => 'Order update webhook',
'obj' => $orderUpdateHookInfo['obj'],
'scope' => $twigGlobals['update_order_scope'],
'aid' => 'order_update_webhook',
'last_webhook_received' => $orderUpdateHookInfo['lastTimeReceived'],
],
'order_status_update_hook' => [
'name' => 'Order status update webhook',
'obj' => $orderStatusUpdateHookInfo['obj'],
'scope' => $twigGlobals['update_order_status_scope'],
'aid' => 'order_update_webhook',
'last_webhook_received' => $orderStatusUpdateHookInfo['lastTimeReceived'],
],
'params' => [
'route' => 'salesforce_CreateOrder',
'slug' => 'salesforce_CreateOrder',
'action_add' => self::ACTION_ADD_ORDER_WEBHOOK,
'action_del' => self::ACTION_RECREATE_ORDER_WEBHOOK,
'url_add' => $addHookDestination,
'url_del' => $delHookDestination
]
],
];
$view = [
'webhook_groups' => $webhooks
];
return $this->render('/salesforce/setting.html.twig', $view);
}
public function SalesAgentDefault($id, LoggerInterface $logger, Request $request, SalesAgentRepository $salesAgentRepository, WebhookManager $hook, EntityManagerInterface $entityManager)
{
// find an active record and make it make it not active
$salesagent_default_remove = $salesAgentRepository->findOneBy(['active' => 1]);
if (!is_null($salesagent_default_remove))
{
$salesagent_default_remove->setActive(0);
$entityManager->persist($salesagent_default_remove);
$entityManager->flush(); // default column remove
}
// find the specified record and make it active
$salesagent_default = $salesAgentRepository->find($id);
$salesagent_default->setActive(1);
$entityManager->persist($salesagent_default);
$entityManager->flush(); // set default column
$destination = $this->generateUrl('salesforcesales_agent', [], UrlGeneratorInterface::ABSOLUTE_URL);
return new RedirectResponse($destination);
}
public function SalesAgent(LoggerInterface $logger, Request $request, SalesAgentRepository $salesAgentRepository, WebhookManager $hook, EntityManagerInterface $entityManager)
{
$action = $request->request->get('action');
if ($action == "save")
{
$bigcommerce_agent_name = $request->request->get('bigcommerce_agent_name');
$salesforcesales_agent_id = $request->request->get('salesforcesales_agent_id');
$salesagent = new SalesAgent();
$salesagent->setName($bigcommerce_agent_name);
$salesagent->setSalesforceId($salesforcesales_agent_id);
$entityManager->persist($salesagent);
$entityManager->flush();
}
if ($action == "delete")
{
$id = $request->request->get('agent_id');
$salesagent = $salesAgentRepository->find($id);
$salesagent->setDeleted(true);
$entityManager->persist($salesagent);
$entityManager->flush();
$response = new JsonResponse();
$json_data['error'] = 0;
$json_data['msg'] = 'Deleted successfully';
$response->setData($json_data);
$response->headers->set('Content-Type', 'application/json');
$response->getContent();
return $response;
}
$customerowner = $salesAgentRepository->findAll();
$view = array(
'customerowner' => $customerowner,
);
return $this->render('/salesforce/salesagent.html.twig',
$view
);
}
public function MarketSegmentDefault($id, MarketSegmentRepository $MarketSegmentRepository, WebhookManager $hook, EntityManagerInterface $entityManager)
{
// find an active record and make it make it not active
$marketsegment_default_remove = $MarketSegmentRepository->findOneBy(['active' => 1]);
if (!is_null($marketsegment_default_remove))
{
$marketsegment_default_remove->setActive(0);
$entityManager->persist($marketsegment_default_remove);
$entityManager->flush(); // default column remove
}
// find the specified record and make it active
$marketsegment_default = $MarketSegmentRepository->find($id);
$marketsegment_default->setActive(1);
$entityManager->persist($marketsegment_default);
$entityManager->flush(); // set default column
$destination = $this->generateUrl('salesforcemarket_segment', [], UrlGeneratorInterface::ABSOLUTE_URL);
return new RedirectResponse($destination);
$json_data['error'] = 0;
$json_data['msg'] = 'successfully updated';
$json_data['hook_id'] = 0;
$response = new JsonResponse();
$response->setData($json_data);
$response->headers->set('Content-Type', 'application/json');
$response->getContent();
return $response;
}
public function MarketSegment(LoggerInterface $logger, Request $request, MarketSegmentRepository $MarketSegmentRepository, WebhookManager $hook, EntityManagerInterface $entityManager)
{
$action = $request->request->get('action');
if ($action == "save")
{
$bigcommerce_name = $request->request->get('bigcommerce_name');
$salesforce_name = $request->request->get('salesforce_name');
$marketsegment = new MarketSegment();
$marketsegment->setBigcommerceName($bigcommerce_name);
$marketsegment->setSalesforceName($salesforce_name);
$entityManager->persist($marketsegment);
$entityManager->flush();
}
if ($action == "delete")
{
$id = $request->request->get('agent_id');
$marketsegment = $MarketSegmentRepository->find($id);
$marketsegment->setDeleted(true);
$entityManager->persist($marketsegment);
$entityManager->flush();
$response = new JsonResponse();
$json_data['error'] = 0;
$json_data['msg'] = 'Deleted successfully';
$response->setData($json_data);
$response->headers->set('Content-Type', 'application/json');
$response->getContent();
return $response;
}
$marketsegment = $MarketSegmentRepository->findAll();
$view = array(
'marketsegment' => $marketsegment,
);
return $this->render('/salesforce/marketsegment.html.twig',
$view
);
}
public function CustomerGroup(LoggerInterface $logger, Request $request, CustomerGroupRepository $CustomerGroupRepository, WebhookManager $hook, EntityManagerInterface $entityManager)
{
$action = $request->request->get('action');
if ($action == "save")
{
$bigcommerce_name = $request->request->get('bigcommerce_name');
$salesforce_name = $request->request->get('salesforce_name');
$customergroup = new CustomerGroup();
$customergroup->setBigcommerceName($bigcommerce_name);
$customergroup->setSalesforceName($salesforce_name);
$entityManager->persist($customergroup);
$entityManager->flush();
}
if ($action == "delete")
{
$id = $request->request->get('agent_id');
$customergroup = $CustomerGroupRepository->find($id);
$customergroup->setDeleted(true);
$entityManager->persist($customergroup);
$entityManager->flush();
$response = new JsonResponse();
$json_data['error'] = 0;
$json_data['msg'] = 'Deleted successfully';
$response->setData($json_data);
$response->headers->set('Content-Type', 'application/json');
$response->getContent();
return $response;
}
$customergroup = $CustomerGroupRepository->findAll();
$view = array(
'customergroup' => $customergroup,
);
return $this->render('/salesforce/customergroup.html.twig',
$view
);
}
/*
* call create order/order-status webhook
*/
public function hook_order_create(Request $request, WebhookManager $hook)
{
return $hook->create($request, $this->module_name);
}
/*
* call recreate order/order-status webhook
*/
public function hook_delete(LoggerInterface $logger, Request $request, WebhookManager $hook, BigCommerceConfig $bigCommerceConfig)
{
return $hook->delete($request, $this->module_name);
}
/**
* Sends email with info
*
* @param string $subject
* @param string $body
*/
protected function sendNotification($subject, $body)
{
if (isset($_ENV['ERROR_EMAIL_ADDRESS'])) {
$mail = MailerFactory::create();
$mail->addAddress($_ENV['ERROR_EMAIL_ADDRESS']);
$mail->setFrom('no-reply@heartmath.com');
$mail->Subject = $subject;
$mail->Body = $body;
$mail->send();
}
}
/**
* Sends email with exception info
*
* @param \Throwable $e
*/
protected function sendErrorNotification(\Throwable $e)
{
if (isset($_ENV['SEND_EMAIL_ON_ERROR'], $_ENV['ERROR_EMAIL_ADDRESS']) && $_ENV['SEND_EMAIL_ON_ERROR']) {
$this->sendNotification(
'Synchronization error: ' . $e->getMessage(),
(string)$e
);
}
}
public function CreateTask(
SalesforceConfig $SalesforceConfig,
$arLog,
$sf_account_id,
$task_subject,
$owner_id,
$logger
) {
try {
$task_priority = 'Normal';
$task_status = 'Completed';
$task_subtype = 'Email';
$task_type = 'Email';
$dtFormat = $this::DT_FORMAT;
$bc_date = $arLog->getCreatedAt();
$offset = timezone_offset_get(new \DateTimeZone('America/Los_Angeles'), $bc_date);
$offset_interval= \DateInterval::createFromDateString((string)$offset . 'seconds');
$email_date = $bc_date->add($offset_interval)->format($this::DT_FORMAT);
$email_body = html_entity_decode(strip_tags($arLog->getBody()),ENT_QUOTES);
$eventData = [
'ActivityDate' => $email_date,
'Description' => $email_body,
'OwnerID' => $owner_id,
'Priority' => $task_priority,
'Status' => $task_status,
'Subject' => $task_subject,
'TaskSubtype' => $task_subtype,
'Type' => $task_type,
'WhatId' => $sf_account_id
];
// $this->dumpToScreen($eventData, 'eventData');
$SalesforceConfig->set_config();
$crud = new CRUD($logger);
// $message .= "Calling '$instance_url' to create event\n";
$sf_email_id = $crud->create('Task', $eventData); #returns id
return array("id" => $sf_email_id, "error" => null);
} catch (\Exception $e) {
// $message .= "Lead Conversion Failed\n";
return array("id" => null, "error" => $e->getMessage());
}
}
/**
* Sync Autoresponder emails to Salesforce
* @param Request $request
* @return Response
*/
public function syncAutoresponderEmails(
Request $request,
SalesforceConfig $SalesforceConfig,
EntityManagerInterface $entityManager,
BigCommerceConfig $bigCommerceConfig,
LoggerInterface $logger,
SalesAgentRepository $salesAgentRepository
) {
try {
$storehash = $_ENV['STOREHASH'];
$config = $bigCommerceConfig->get_app_detail();
Bigcommerce::configure(array(
'client_id' => $_ENV['CLIENT_ID'],
'auth_token' => $config[$storehash]['access_token'],
'store_hash' => $storehash
));
$SalesforceConfig->set_config();
// Retrieve list of new AutoresponderLogs
$arLogRepo = $entityManager->getRepository(AutoResponderLog::class);
$arLogs = $arLogRepo->findBy(array(
'sf_sync_status' => AutoResponderLog::SF_SYNC_STATUS_NEW
), array('order_id' => 'ASC', 'id' => 'ASC'), 10);
$customerRepo = $entityManager->getRepository(Customer::class);
if (count($arLogs)) {
$api_url_path = $bigCommerceConfig->get_api_url();
$data_string = "";
$customrequest = "GET";
$salesagent_default = $salesAgentRepository->findOneBy(['active' => 1])->getSalesforceId();
$arRepo = $entityManager->getRepository(Autoresponder::class);
$last_order_id = 0;
foreach ($arLogs as $arLog) {
$order_id = $arLog->getOrderId();
// $this->dumpToScreen($arLog, 'arLog');
// Check if this arLog is from the same order; if it is,
// we don't need to retrieve it again
if ($order_id !== $last_order_id) {
// Get order and details from BigCommerce
$api_url = "$api_url_path/v2/orders/".$order_id;
$bc_order = $SalesforceConfig->curl($api_url, $data_string, $customrequest);
// $this->dumpToScreen($bc_order, 'BC Order');
$bc_customer_id = $bc_order['customer_id'];
$customer = $customerRepo->findOneBy(['bc_id' => $bc_customer_id]);
}
if (!empty($customer)) {
// We found a record with a BigCommerce ID corresponding to a Salesforce ID,
// so we can proceed to attach the email.
$autoresponder = $arRepo->findOneBy(['Sku' => $arLog->getSku()]);
if (isset($autoresponder)) {
$subject = $autoresponder->getSubject();
} else {
$subject = 'AutoResponder SKU Not Found - Default Subject';
}
$sf_customer_id = $customer->getSfId();
// $this->dumpToScreen($customerStatus, 'customerStatus');
// Mark the record as processing
$arLog->setSfSyncStatus(AutoResponderLog::SF_SYNC_STATUS_PROCESSING);
$entityManager->persist($arLog);
$entityManager->flush();
$result = $this->CreateTask(
$SalesforceConfig,
$arLog,
$sf_customer_id,
$subject,
$salesagent_default,
$logger
);
if (isset($result['id'])) {
$arLog->setSfSyncStatus(AutoResponderLog::SF_SYNC_STATUS_COMPLETE);
$entityManager->persist($arLog);
$entityManager->flush();
} elseif (isset($result['error'])) {
$logger->error("Error - SalesforceController syncAutoresponderEmails arLog " . $arLog->getId() . "Error: " . $result['error']);
$arLog->setSfSyncStatus(AutoResponderLog::SF_SYNC_STATUS_ERROR);
$entityManager->persist($arLog);
$entityManager->flush();
} else {
//Don't know what happened
$logger->error("Unknown Outcome - SalesforceController syncAutoresponderEmails arLog " . $arLog->getId());
$arLog->setSfSyncStatus(AutoResponderLog::SF_SYNC_STATUS_SKIP);
$entityManager->persist($arLog);
$entityManager->flush();
}
} else {
// No customer status record found with a BC ID associated to a SF ID. Other
// processes should fill this in, so skip this time around.
// $this->dumpToScreen("Order # $order_id sf_id not found", 'Skipped');
$logger->info("Autoresponder Email Sync - Order # $order_id sf_id not found. Will retry.");
// Mark the record as new so it can be retried
$arLog->setSfSyncStatus(AutoResponderLog::SF_SYNC_STATUS_NEW);
$entityManager->persist($arLog);
$entityManager->flush();
}
$last_order_id = $order_id;
}
}
} catch (\Exception $e) {
$logger->error("Error - SalesforceController syncAutoresponderEmails" . $e->getMessage());
$this->sendNotification(
'App Error - SalesforceController syncAutoresponderEmails',
str_replace("\u0000","",json_encode((array)$e, JSON_PRETTY_PRINT))
);
}
$response = new Response();
// $response->headers->set('Content-Type', 'text/xml');
// $response->headers->set('Content-Type', 'text/html');
$response->headers->set('Content-Type', 'text/html');
// $this->logger->info("process Orders: " . json_encode((array)$orders));
return $this->render('salesforce/syncAutoresponderEmails.html.twig', array(
'arLogs' => $arLogs
));
}
private function deleteAppsyncCustomer(
Customer $customer,
EntityManagerInterface $entityManager,
LoggerInterface $logger
) {
//Delete the customer record in the db
$logger->info("SF delete - remove appsync database record: ID: " .
$customer->getId() .
", Email: " . $customer->getEmailAddress() .
", BC ID: " . $customer->getBcId() .
", SF ID: " . $customer->getSfId()
);
$entityManager->remove($customer);
$entityManager->flush();
}
/**
* Move BigCommerce orders to a customer
*
* @param array $bcOrders
* @param int $bcCustomerIdNew
* @return array Orders data
*/
private function moveBcOrdersToCustomer(
$bcOrders,
$bcCustomerIdNew,
EntityManagerInterface $entityManager,
LoggerInterface $logger,
BigCommerceClient $bigCommerceClient
): array
{
$commRepo = $entityManager->getRepository(Comm::class);
$bc_orders_updated = array();
foreach ($bcOrders as $bcOrder) {
$dtEnd = new \DateTime;
$comm = new Comm();
$comm->setService(Comm::SERVICE_ORDER);
$comm->setType(Comm::TYPE_BC_UPDATE);
$comm->setDtCreated($dtEnd);
$comm->setStatus(Comm::STATUS_NEW);
$entityManager->persist($comm);
$entityManager->flush();
$commId = $comm->getId();
try {
$params = [
'customer_id' => $bcCustomerIdNew
];
$comm = $commRepo->find($commId);
$comm->setRequest(__METHOD__ . ' BigCommerceClient updateOrder. OrderId: ' . $bcOrder->id . '. Params: ' . $this->encodeJson($params));
$logger->info("SalesforceController moveBcOrdersToCustomer: Order ID: $bcOrder->id, Old Customer ID: $bcOrder->customer_id, New Customer ID: $bcCustomerIdNew");
$bc_order = $bigCommerceClient->updateOrder($bcOrder->id, $params);
$bc_orders_updated[] = $bc_order;
$comm->setContent($this->encodeJson($bc_order));
$comm->setStatus(Comm::STATUS_COMPLETE);
$entityManager->persist($comm);
$entityManager->flush();
} catch(\Exception $e) {
$logger->error("Error - Comparator moveBcOrdersToCustomer: Order ID: $$bcOrder->id New Customer ID: $bcCustomerIdNew" . $e->getMessage());
$comm->setResponse($this->encodeJson($e));
$comm->setStatus(Comm::STATUS_ERROR);
$entityManager->persist($comm);
$entityManager->flush();
}
}
return $bc_orders_updated;
}
/**
* Get BigCommerce order IDs for specific customer
*
* @param int $bcCustomerId
* @return array Orders data
*/
private function listBcOrdersByCustomerId(
$bcCustomerId,
BigCommerceClient $bigCommerceClient,
EntityManagerInterface $entityManager,
LoggerInterface $logger
): ?array
{
$commRepo = $entityManager->getRepository(Comm::class);
$dtEnd = new \DateTime;
$comm = new Comm();
$comm->setService(Comm::SERVICE_ORDER);
$comm->setType(Comm::TYPE_BC_LIST);
$comm->setDtCreated($dtEnd);
$comm->setStatus(Comm::STATUS_NEW);
$entityManager->persist($comm);
$entityManager->flush();
$commId = $comm->getId();
try {
$bc_orders = array();
$params = [
'customer_id' => $bcCustomerId
];
$comm = $commRepo->find($commId);
$comm->setRequest(__METHOD__ . ' bigCommerceClient->getOrders. Params: ' . $this->encodeJson($params));
$bc_orders = $bigCommerceClient->getOrders($params);
$comm->setResponse($this->encodeJson($bc_orders));
$comm->setStatus(Comm::STATUS_COMPLETE);
$entityManager->persist($comm);
$entityManager->flush();
return $bc_orders;
} catch(\Exception $e) {
$logger->error("Error - Comparator listBcOrdersByCustomerId: " . $e->getMessage());
$comm->setResponse($this->encodeJson($e));
$comm->setStatus(Comm::STATUS_ERROR);
$entityManager->persist($comm);
$entityManager->flush();
}
return [];
}
/**
* Salesforce Customer Delete Webhook Endpoint
* @param Request $request
* @return Response
*/
public function CustomerDelete(
Request $request,
SalesforceConfig $SalesforceConfig,
EntityManagerInterface $entityManager,
BigCommerceConfig $bigCommerceConfig,
LoggerInterface $logger,
BigCommerceClient $bigCommerceClient,
\App\Service\Customer\SalesForce\Converter $salesForceCustomerConverter
) {
try {
$storehash = $_ENV['STOREHASH'];
$config = $bigCommerceConfig->get_app_detail();
BigCommerceClient::configure(array(
'client_id' => $_ENV['CLIENT_ID'],
'auth_token' => $config[$storehash]['access_token'],
'store_hash' => $storehash
));
$SalesforceConfig->set_config();
$crud = new CRUD($logger);
// Retrieve list of newly deleted customers
$commRepo = $entityManager->getRepository(Comm::class);
$comms = $commRepo->findBy(array(
'service' => Comm::SERVICE_CUSTOMER,
'type' => Comm::TYPE_SF_RECEIVE_HOOK,
'status' => Comm::STATUS_NEW
), array('id' => 'ASC'), 10);
if (count($comms)) {
$customerRepo = $entityManager->getRepository(Customer::class);
$sfLosers = []; //keep all records that are merge losers
foreach ($comms as $comm) {
$commId = $comm->getId();
$comm->setStatus(Comm::STATUS_PROCESSING);
$entityManager->persist($comm);
$entityManager->flush();
$comm = $commRepo->find($commId);
$content = json_decode($comm->getContent(), true);
$sfLosers = $content['old'];
foreach ($sfLosers as $sfLoser) {
$customerId = null;
$customerEmail = null;
$customerSageId = null;
$isBusinessAccount = false;
$customer = null;
$customer = $customerRepo->findOneBy(['sf_id' => $sfLoser[SFField::FIELD_ID]]);
if ($customer) {
$customerId = $customer->getBcId();
$customerEmail = $customer->getEmailAddress();
$customerSageId = $customer->getSageId();
$isBusinessAccount = $customer->isBusinessAccount();
}
if (!$customerId) {
// No customer found in appsync db. For now, we will dump out of the process.
// In prod, every SF customer SHOULD be in BC and the appsync db. If it is not,
// something is wrong with this record and we will ignore for now.
$logger->error(__METHOD__ . ' Customer not found in appsync db: ' . $sfLoser['Id']);
$comm->setStatus(Comm::STATUS_COMPLETE);
$entityManager->persist($comm);
$entityManager->flush();
break;
}
$master = null;
$merged = false; // true if a merge with a master record, false if a straight delete in SF
if (array_key_exists(SFField::FIELD_MASTER_RECORD_ID, $sfLoser) && $sfLoser[SFField::FIELD_MASTER_RECORD_ID]) { //merge
$merged = true;
$masterSfId = $sfLoser[SFField::FIELD_MASTER_RECORD_ID] ?: null;
//Now let's find the winner customer record to the merged record for the next processing steps.
if ($masterSfId) {
$master = $customerRepo->findOneBy(['sf_id' => $masterSfId]);
}
}
if ($merged && !$master) {
// No record of a master customer in appsync db; check for a duplicate email.
// We do this because when an email address is duplicated in SF, one of the possible
// outcomes is the single appsync db record flips between the two SF accounts.
$sfAccount = $crud->query(
"SELECT Id, PersonEmail, MAS90_Account_ID__c FROM Account WHERE Id = '$masterSfId' ORDER BY LastModifiedDate DESC LIMIT 1"
);
if ($sfAccount) {
// We have found a master record in Salesforce that is not in the appsync db.
// Check if it's a dupe identifier; if so, we just need to update the appsync db
// to the correct master record and trigger a sync.
//
// In this case, the BC ID in the record should already be correct, as there can
// be no duplicate email address.
if (((!$isBusinessAccount) &&
$customerEmail == $sfAccount[SFField::FIELD_PERSONAL_EMAIL])
|| (($isBusinessAccount) &&
($customerSageId == $sfAccount[SFField::FIELD_MAS90_ACC_ID]))
) {
$logger->info(__METHOD__ . ' SFCustomer duplicate email or business Sage ID, single record in appsync db - update appsync record and trigger sync: ' . $sfLoser['Id']);
$customer->setSfId($masterSfId);
$comm->setStatus(Comm::STATUS_COMPLETE);
$entityManager->persist($comm);
$entityManager->flush();
$customer = $customerRepo->find($customerId);
$salesForceCustomerConverter->exportCustomer($customer);
break;
}
}
}
if ($merged && $master) {
// Master record found in appsync db. Check if it's a duplicate email. If so,
// the orders in BC should ALREADY be attached to the correct customer account, as
// customer email address is UNIQUE in BC. We don't want to delete the BC customer as
// the "winner" is the same as the "loser" in this case.
if (((!$isBusinessAccount) &&
$customerEmail == $master->getEmailAddress())
|| ($isBusinessAccount &&
($customer->getSageId() == $master->getSageId()))
) {
$logger->info(__METHOD__ . ' SFCustomer duplicate email or business Sage ID - only delete appsync record: ' . $sfLoser['Id']);
$this->deleteAppsyncCustomer($customer, $entityManager, $logger);
$comm->setStatus(Comm::STATUS_COMPLETE);
$entityManager->persist($comm);
$entityManager->flush();
break;
}
// check for orders on the account
$bcOrders = $this->listBcOrdersByCustomerId($customerId, $bigCommerceClient, $entityManager, $logger);
$logger->info(__METHOD__ . ' bcOrders: ' . $this->encodeJson($bcOrders));
if ($bcOrders) { // if orders:
if ($master->getBcId()) {
$newOrderCustomerId = $master->getBcId();
$this->moveBcOrdersToCustomer($bcOrders, $newOrderCustomerId, $entityManager, $logger, $bigCommerceClient);
}
}
}
//Delete the customer record in BigCommerce
$logger->info("SF merge loser, deleting BC ID: " . $customer->getBcId());
$bigCommerceClient->deleteCustomer($customer->getBcId());
$this->deleteAppsyncCustomer($customer, $entityManager, $logger);
}
$comm->setStatus(Comm::STATUS_COMPLETE);
$entityManager->persist($comm);
$entityManager->flush();
}
}
} catch (\Exception $e) {
$logger->error("Error - SalesforceController CustomerDelete" . $e->getMessage());
$this->sendNotification(
'App Error - SalesforceController CustomerDelete',
str_replace("\u0000","",json_encode((array)$e, JSON_PRETTY_PRINT))
);
}
$response = new Response();
return $response;
}
/**
* Receive Customer Updates From Salesforce
* @param Request $request
* @return Response
*/
public function SalesforceCustomer(
Request $request,
EntityManagerInterface $entityManager,
LoggerInterface $logger
) {
try {
$logger->debug("Salesforce customer delete: " . $this->encodeJson($request->getContent()));
$content = $request->getContent();
$comm = new Comm();
$comm->setService(Comm::SERVICE_CUSTOMER);
$comm->setType(Comm::TYPE_SF_RECEIVE_HOOK);
$comm->setDtCreated((\DateTime::createFromFormat('Y-m-d H:i:s', date('Y-m-d H:i:s', time()))));
$comm->setStatus(Comm::STATUS_NEW);
$comm->setRequest($this->encodeJson($request));
$comm->setContent($content);
$comm->setHttpStatus(Response::HTTP_OK);
$entityManager->persist($comm);
$entityManager->flush();
} catch (\Exception $e) {
$logger->error("Error - SalesforceController SalesforceCustomer" . $e->getMessage());
}
$response = new Response();
$response->setStatusCode(204);
return $response;
}
private function encodeJson($valueIn, $jsonOptions = 0) {
if (is_object($valueIn)) {
return str_replace("\u0000","",str_replace("\u0000*\u0000","",json_encode((array)$valueIn, $jsonOptions)));
} else if (is_array($valueIn) || is_iterable($valueIn)) {
return json_encode((array)$valueIn, $jsonOptions);
}
return json_encode($valueIn, $jsonOptions);
}
}