src/Service/SalesforceService.php line 54

Open in your IDE?
  1. <?php 
  2. namespace App\Service;
  3. use App\Entity\Donation;
  4. use App\Service\ApiService;
  5. use App\Entity\FilmProject;
  6. use App\Entity\FilmProjectMember;
  7. use App\Entity\FilmProjectProgressReport;
  8. use App\Entity\FilmProjectProgressReportFile;
  9. use App\Entity\OrderBillingDetails;
  10. use App\Entity\OrderDetails;
  11. use App\Entity\User;
  12. use App\String\Constant;
  13. use App\Serializer\SalesforceObjectConverter;
  14. use App\Utility\SalesforceValues;
  15. use bjsmasth\Salesforce\Authentication\PasswordAuthentication;
  16. use bjsmasth\Salesforce\CRUD;
  17. use GuzzleHttp\Exception\ClientException;
  18. use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
  19. use Exception;
  20. final class SalesforceService extends ApiService
  21. {
  22.     private ContainerBagInterface $params;
  23.     private CRUD $salesforceCrud;
  24.     private SalesforceObjectConverter $salesforceObjectConverter;
  25.     public function __construct(ContainerBagInterface $paramsSalesforceObjectConverter $salesforceObjectConverter)
  26.     {
  27.         $this->params $params;
  28.         $this->salesforceObjectConverter $salesforceObjectConverter;
  29.         $this->salesforceCrud $this->authenticate();
  30.     }
  31.     
  32.     /**
  33.      * Setup access token and instance URL in session
  34.      *
  35.      * @return void
  36.      */
  37.     public function authenticate() 
  38.     {
  39.         $options = [
  40.             'grant_type' => 'password',
  41.             'client_id' => $this->params->get('app.salesforce_client_id'),
  42.             'client_secret' => $this->params->get('app.salesforce_client_secret'),
  43.             'username' => $this->params->get('app.salesforce_username'),
  44.             'password' => $this->params->get('app.salesforce_password'),
  45.         ];
  46.         $salesforce = new PasswordAuthentication($options);
  47.         $salesforce->setEndpoint(Constant::SALESFORCE_TOKEN_URL);
  48.         $salesforce->authenticate();
  49.         return new CRUD();
  50.     }
  51.     /**
  52.      * get contact ID if exists, return false if doesnt exists
  53.      *
  54.      * @param User $user
  55.      * @return string|void
  56.      */
  57.     public function getContact(string $email)
  58.     {
  59.         try {
  60.             $query 'SELECT Id FROM Contact WHERE Email = \''$email .'\'';
  61.             $result $this->salesforceCrud->query($query);
  62.         } catch (ClientException $e) {
  63.             $response $e->getResponse();
  64.             $responseBodyAsString $response->getBody()->getContents();
  65.             $this->throwExceptionMessage($responseBodyAsString);
  66.             return null;
  67.         }
  68.         if ($result['totalSize'] <= 0) {
  69.             return false;
  70.         }
  71.         $id $result['records'][0]['Id'];
  72.         return $id;
  73.     }
  74.      /**
  75.      * get contact ID if exists, return false if doesnt exists
  76.      *
  77.      * @param User $user
  78.      * @return string|void
  79.      */
  80.     public function getContactByEmailandFullName(string $firstNamestring $lastNamestring $email)
  81.     {
  82.         // $firstName = preg_replace('/[^a-zA-Z0-9\s]/', '\\\\$0', $firstName);
  83.         // $lastName = preg_replace('/[^a-zA-Z0-9\s]/', '\\\\$0', $lastName);
  84.         // $firstName = str_replace("'", "''", $firstName);
  85.         // $lastName = str_replace("'", "''", $lastName);
  86.         $firstName str_replace("'""\\'"$firstName);
  87.         $lastName  str_replace("'""\\'"$lastName);
  88.         try {
  89.             $query 'SELECT Id FROM Contact WHERE Email = \''$email .'\' AND FirstName = \''$firstName .'\' AND LastName = \''$lastName .'\'';
  90.             $result $this->salesforceCrud->query($query);
  91.         } catch (ClientException $e) {
  92.             $response $e->getResponse();
  93.             $responseBodyAsString $response->getBody()->getContents();
  94.             $this->throwExceptionMessage($responseBodyAsString);
  95.             return null;
  96.         }
  97.         if ($result['totalSize'] <= 0) {
  98.             // Fallback: Last check by email 
  99.             // $id = $this->getContact($email);
  100.             // return $id ?? false;
  101.              // Removed fallback: do not check by email only
  102.             return false;
  103.         }
  104.         $id $result['records'][0]['Id'];
  105.         return $id;
  106.     }
  107.     /**
  108.      * get contact ID if exists, return false if doesnt exists
  109.      *
  110.      * @param User $user
  111.      * @return string|void
  112.      */
  113.     public function getContactByFullName(string $firstNamestring $lastNamestring $email)
  114.     {
  115.         // $firstName = preg_replace('/[^a-zA-Z0-9\s]/', '\\\\$0', $firstName);
  116.         // $lastName = preg_replace('/[^a-zA-Z0-9\s]/', '\\\\$0', $lastName);
  117.         $firstName str_replace("'""''"$firstName);
  118.         $lastName str_replace("'""''"$lastName);
  119.         
  120.         $query 'SELECT Id FROM Contact WHERE FirstName = \''$firstName .'\' AND LastName = \''$lastName .'\'';
  121.         $result $this->salesforceCrud->query($query);
  122.         if ($result['totalSize'] <= 0) {
  123.             return false;
  124.         }
  125.         $id $result['records'][0]['Id'];
  126.         if ($result['totalSize'] > 1) {
  127.             $id $this->getContact($email);
  128.         }
  129.         return $id;
  130.     }
  131.     /**
  132.      * Create salesforce contact obj
  133.      *
  134.      * @param User $user
  135.      * @return string
  136.      */
  137.     public function createContact(User $user): string
  138.     {
  139.         $id $this->getContact($user->getEmail());
  140.         // $id = $this->getContactByEmailandFullName($user->getFirstName(), $user->getLastName(), $user->getEmail());
  141.         if (!$id) {
  142.             $data =  $this->salesforceObjectConverter->convertUserToContact($user);
  143.         
  144.             $id $this->salesforceCrud->create(Constant::CONTACT_OBJ$data);  #returns id
  145.         }
  146.     
  147.         return $id;
  148.     }
  149.     /**
  150.      * Update Salesforce contact obj
  151.      *
  152.      * @param User $user
  153.      * @return void
  154.      */
  155.     public function updateContact(User $user)
  156.     {
  157.         $userInformation $user->getUserInformation();
  158.         $id $userInformation->getSalesforceId();
  159.         $data =  $this->salesforceObjectConverter->convertUserToContact($user);
  160.         
  161.         $this->salesforceCrud->update(Constant::CONTACT_OBJ$id$data);  #returns id
  162.     }
  163.     /**
  164.      * Create contact salesforce object from FilmProjectMember entity
  165.      *
  166.      * @param FilmProjectMember $filmProjectMember
  167.      * @return void|string
  168.      */
  169.     public function createContactFromFilmMember(FilmProjectMember $filmProjectMember)
  170.     {
  171.         $id $this->getContact($filmProjectMember->getEmail());
  172.         // $id = $this->getContactByEmailandFullName($filmProjectMember->getName(), $filmProjectMember->getLastName(), $filmProjectMember->getEmail());
  173.         if (!$id) {
  174.             $data $this->salesforceObjectConverter->convertFilmMemberToContact($filmProjectMember);            
  175.             try {
  176.                 $id $this->salesforceCrud->create(Constant::CONTACT_OBJ$data);  #returns id
  177.             } catch (ClientException $e) {
  178.                 $response $e->getResponse();
  179.                 $responseBodyAsString $response->getBody()->getContents();
  180.                 $this->throwExceptionMessage($responseBodyAsString);
  181.                 // var_dump($responseBodyAsString); exit();
  182.             }
  183.         }
  184.     
  185.         return $id;
  186.     }
  187.     /**
  188.      * Update contact salesforce object from FilmProjectMember entity
  189.      *
  190.      * @param FilmProjectMember $filmProjectMember
  191.      * @return void|string
  192.      */
  193.     public function updateContactFromFilmMember(FilmProjectMember $filmProjectMember)
  194.     {
  195.         $salesforceId $filmProjectMember->getSalesforceId();
  196.         if (!$salesforceId) {
  197.             $data $this->salesforceObjectConverter->convertFilmMemberToContact($filmProjectMember);            
  198.             try {
  199.                 $this->salesforceCrud->update(Constant::CONTACT_OBJ$salesforceId$data);  #returns id
  200.             } catch (ClientException $e) {
  201.                 $response $e->getResponse();
  202.                 $responseBodyAsString $response->getBody()->getContents();
  203.                 $this->throwExceptionMessage($responseBodyAsString);
  204.             }
  205.         }
  206.     }
  207.     /**
  208.      * Create salesforce contact obj
  209.      *
  210.      * @param User $user
  211.      * @return string
  212.      */
  213.     public function createGuestContactFromOrderDetails(OrderBillingDetails $orderBillingDetails): ?string
  214.     {
  215.         // $id = $this->getContactByEmailandFullName($orderBillingDetails->getFirstName(), $orderBillingDetails->getLastName(), $orderBillingDetails->getEmailAddress()) ?? $this->getContact($orderBillingDetails->getEmailAddress());
  216.         $id $this->getContactByEmailandFullName($orderBillingDetails->getFirstName(), $orderBillingDetails->getLastName(), $orderBillingDetails->getEmailAddress());
  217.         if (!$id) {
  218.             $data =  $this->salesforceObjectConverter->convertBillingDetailsToContact($orderBillingDetails);
  219.             $id $this->salesforceCrud->create(Constant::CONTACT_OBJ$data);  #returns id
  220.         }
  221.     
  222.         return $id;
  223.     }
  224.     /**
  225.      * Create account salesforce object from film member on film application
  226.      *
  227.      * @return void|string
  228.      */
  229.     public function createAccount(string $organisationNamestring $primaryContactSfId null)
  230.     {
  231.         if ($organisationName) {
  232.             $id $this->getAccount($organisationName);
  233.             if (!$id) {
  234.                 $data = [
  235.                     'Name' => $organisationName,
  236.                     'RecordTypeId' => Constant::SALESFORCE_ORGANISATION_FILMMAKER,
  237.                 ];
  238.                 if ($primaryContactSfId) {
  239.                     $data['npe01__One2OneContact__c'] = $primaryContactSfId;
  240.                 }
  241.                 
  242.                 $id $this->salesforceCrud->create(Constant::ACCOUNT_OBJ$data);  #returns id
  243.             } else {
  244.                 if ($primaryContactSfId) {
  245.                     // $data['npe01__One2OneContact__c'] = $primaryContactSfId;
  246.                     // $statusCode = $this->salesforceCrud->update(Constant::ACCOUNT_OBJ, $id, $data);  // Update Account
  247.                     $data = [
  248.                         'npsp__Primary_Affiliation__c' => $id
  249.                     ];
  250.                     
  251.                     $this->salesforceCrud->update(Constant::CONTACT_OBJ$primaryContactSfId$data); // Update contact affiliation to account
  252.                 }
  253.             }
  254.             
  255.             return $id;
  256.         }
  257.         return false;
  258.     }
  259.     /**
  260.      * Create account salesforce object from film member on film application
  261.      *
  262.      * @return void|string
  263.      */
  264.     public function createAccountWithOrderDetails(string $organisationName, ?OrderDetails $orderDetails null, ?string $primaryContactSfId null)
  265.     {
  266.         if ($organisationName) {
  267.             $id $this->getAccount($organisationName);
  268.             $data = [];
  269.             if ($orderDetails) {
  270.                 $orderBillingDetails $orderDetails->getOrderBillingDetails();
  271.                 if ($orderBillingDetails) {
  272.                     $data['Email__c'] = $orderBillingDetails->getEmailAddress();
  273.                     $data['Phone'] = $orderBillingDetails->getPhoneNumber();
  274.                     $data['BillingStreet'] = $orderBillingDetails->getStreet();
  275.                     $data['BillingState'] = $orderBillingDetails->getState();
  276.                     $data['BillingPostalCode'] = $orderBillingDetails->getPostcode();
  277.                     $data['BillingCountry'] = $orderBillingDetails->getCountry();
  278.                     $data['BillingCity'] = $orderBillingDetails->getSuburb();
  279.                 }
  280.             }
  281.             if (!$id) {
  282.                 $data['Name'] = $organisationName;
  283.                 $data['RecordTypeId'] = Constant::SALESFORCE_ORGANISATION_FILMMAKER;
  284.                 if ($primaryContactSfId) {
  285.                     $data['npe01__One2OneContact__c'] = $primaryContactSfId;
  286.                 }
  287.                 // TODO: IF not exists, create account with primary contact
  288.                 $id $this->salesforceCrud->create(Constant::ACCOUNT_OBJ$data);  #returns id
  289.             } else {
  290.                 // TODO: IF exists, update account with affiliate contact
  291.                 if ($primaryContactSfId) {
  292.                     // Update organisation salesforce object
  293.                     
  294.                     try {
  295.                         $data['npe01__One2OneContact__c'] = $primaryContactSfId;
  296.                         $statusCode $this->salesforceCrud->update(Constant::ACCOUNT_OBJ$id$data);  // Update Account
  297.                     } catch (ClientException $e) {
  298.                     }
  299.                     // Update Contact Object
  300.                     try {
  301.                         $contactData = ['npsp__Primary_Affiliation__c' => $id];
  302.                         $this->salesforceCrud->update(Constant::CONTACT_OBJ$primaryContactSfId$contactData); // Update contact affiliation to account
  303.                     } catch (ClientException $e) {
  304.                     }
  305.                 }
  306.             }
  307.             
  308.             return $id;
  309.         }
  310.         return false;
  311.     }
  312.     /**
  313.      * get organisation ID if exists, return false if doesnt exists
  314.      *
  315.      * @param User $user
  316.      * @return void
  317.      */
  318.     public function getAccount(string $organisationName)
  319.     {
  320.         $organisationName addslashes($organisationName);
  321.         $query 'SELECT Id FROM Account WHERE Name = \''$organisationName .'\'';
  322.         $result $this->salesforceCrud->query($query);
  323.         if ($result['totalSize'] <= 0) {
  324.             return false;
  325.         }
  326.         $id $result['records'][0]['Id'];
  327.         return $id;
  328.     }
  329.     /**
  330.      * Create account salesforce object from film member on film application
  331.      *
  332.      * @return void|string
  333.      */
  334.     public function createAccountFromFilmProjectMember(FilmProjectMember $filmProjectMember)
  335.     {
  336.         if ($organisationName $filmProjectMember->getOrganisation()) {
  337.             $id $this->getAccount($organisationName);
  338.             if (!$id) {
  339.                 $data = [
  340.                     'Name' => $organisationName,
  341.                     'RecordTypeId' => Constant::SALESFORCE_ORGANISATION_FILMMAKER,
  342.                 ];
  343.                 
  344.                 $id $this->salesforceCrud->create(Constant::ACCOUNT_OBJ$data);  #returns id
  345.             }
  346.         
  347.             return $id;
  348.         }
  349.         return false;
  350.     }
  351.     /**
  352.      * Create campaign object from film project entity
  353.      *
  354.      * @param FilmProject $filmProject
  355.      * @return void|string
  356.      */
  357.     public function createCampaign(FilmProject $filmProject)
  358.     {
  359.         $id null;
  360.         if (!empty($filmProject->getOldWordpressId())) {
  361.             $id $this->getCampaignByWordpressId($filmProject->getOldWordpressId());
  362.         } 
  363.         if (!$id) {
  364.             $data $this->salesforceObjectConverter->convertProjectToCampaign($filmProject);
  365.             try {
  366.                 $id $this->salesforceCrud->create(Constant::CAMPAIGN_OBJ$data); 
  367.             } catch (ClientException $e) {
  368.                 $response $e->getResponse();
  369.                 $responseBodyAsString $response->getBody()->getContents();
  370.                 $this->throwExceptionMessage($responseBodyAsString);
  371.                 return null;
  372.             }
  373.         }
  374.     
  375.         return $id;
  376.     }
  377.     /**
  378.      * Update campaign object from film project entity
  379.      *
  380.      * @param FilmProject $filmProject
  381.      * @return void
  382.      */
  383.     public function updateCampaign(FilmProject $filmProject)
  384.     {
  385.         $salesforceId $filmProject->getSalesforceId();
  386.         $data $this->salesforceObjectConverter->convertProjectToCampaign($filmProjecttrue);
  387.         try {
  388.             $id $this->salesforceCrud->update(Constant::CAMPAIGN_OBJ$salesforceId$data); 
  389.         } catch (ClientException $e) {
  390.             $response $e->getResponse();
  391.             $responseBodyAsString $response->getBody()->getContents();
  392.             $this->throwExceptionMessage($responseBodyAsString);
  393.             var_dump($responseBodyAsString); exit();
  394.         }
  395.     
  396.         return $id;
  397.     }
  398.     public function updateCampaignAdmin(FilmProject $filmProject) {
  399.         $salesforceId $filmProject->getSalesforceId();
  400.         $data = [
  401.             'Application_Fee_Paid__c' => 0,
  402.             'Application_Fee_Amount__c' => 0,
  403.         ];
  404.         try {
  405.             $id $this->salesforceCrud->update(Constant::CAMPAIGN_OBJ$salesforceId$data); 
  406.         } catch (ClientException $e) {
  407.             $response $e->getResponse();
  408.             $responseBodyAsString $response->getBody()->getContents();
  409.             $this->throwExceptionMessage($responseBodyAsString);
  410.             var_dump($responseBodyAsString); exit();
  411.         }
  412.         return $id;
  413.     }
  414.     /**
  415.      * Update campaign object to be approved
  416.      *
  417.      * @param FilmProject $filmProject
  418.      * @return void
  419.      */
  420.     public function approveCampaign(FilmProject $filmProject
  421.     {
  422.         $salesforceId $filmProject->getSalesforceId();
  423.         $updatedData = [
  424.             'Project_Approved__c' => 1,
  425.             // 'Project_Approval_Date__c' => (new \DateTime('today'))->format('Y-m-d'),
  426.             'Wordpress_ID__c' => $filmProject->getWordpressId() ? $filmProject->getWordpressId() : '',
  427.             // 'Wordpress_ID_2023__c' => $filmProject->getWordpressId() ? $filmProject->getWordpressId() : '',
  428.             'IsActive' => 1,
  429.             'Status' => 'Completed'
  430.         ];
  431.         
  432.         if ($filmProject->getOldWordpressId()) { // If an old migrated project
  433.             $updatedData['Wordpress_ID__c'] = $filmProject->getOldWordpressId();
  434.         } else { // New project
  435.             $updatedData['Project_Approval_Date__c'] = (new \DateTime('today'))->format('Y-m-d');
  436.         }
  437.         $statusCode =  $this->salesforceCrud->update(Constant::CAMPAIGN_OBJ$salesforceId$updatedData);
  438.     }
  439.     /**
  440.      * Updated campaign object to be declined
  441.      *
  442.      * @param FilmProject $filmProject
  443.      * @return void
  444.      */
  445.     public function declineCampaign(FilmProject $filmProject)
  446.     {
  447.         $salesforceId $filmProject->getSalesforceId();
  448.         $updatedData = [
  449.             'Project_Approved__c' => 0,
  450.             'Rejected_Date__c' => (new \DateTime('today'))->format('Y-m-d'),
  451.             'Resubmit__c' => 0,
  452.         ];
  453.         $statusCode =  $this->salesforceCrud->update(Constant::CAMPAIGN_OBJ$salesforceId$updatedData);
  454.     }
  455.     /**
  456.      * Updated campaign object to be asked to resubmit
  457.      *
  458.      * @param FilmProject $filmProject
  459.      * @return void
  460.      */
  461.     public function resubmitCampaign(FilmProject $filmProject)
  462.     {
  463.         $salesforceId $filmProject->getSalesforceId();
  464.         $updatedData = [
  465.             'Project_Approved__c' => 0,
  466.             // 'Rejected_Date__c' => (new \DateTime('today'))->format('Y-m-d'),
  467.             'Status' => 'In Progress',
  468.             'Resubmit__c' => 1,
  469.         ];
  470.         $statusCode =  $this->salesforceCrud->update(Constant::CAMPAIGN_OBJ$salesforceId$updatedData);
  471.     }
  472.     /**
  473.      * Create Film Application Transaction
  474.      *
  475.      * @param FilmProject $filmProject
  476.      * @param OrderDetails $orderDetails
  477.      * @return string
  478.      */
  479.     public function createFilmApplicationTransaction(FilmProject $filmProject)
  480.     {
  481.         $orderDetails $filmProject->getOrderDetails();
  482.         $projectOwner $filmProject->getOwner();
  483.         $accountName sprintf('%s (%s) Household'$projectOwner->getLastName(), $projectOwner->getFirstName());
  484.         
  485.         $ownerAccountId "";
  486.         $ownerSfId $this->getContact($projectOwner->getEmail());
  487.         if ($ownerSfId) {
  488.             $ownerAccountId $this->createAccountWithOrderDetails($accountName$orderDetails$ownerSfId);
  489.         } else {
  490.             $ownerAccountId $this->createAccountWithOrderDetails($accountName$orderDetails);
  491.         }
  492.         $data = [
  493.             'RecordTypeId' => Constant::SALESFORCE_TRANSACTION_TRANSACTION,
  494.             'Name' => 'Film Application - '$filmProject->getTitle(),
  495.             'AccountId' =>  $ownerAccountId,
  496.             // 'npsp__Primary_Contact__c' => $projectOwner->getUserInformation()->getSalesforceId(),
  497.             'LeadSource' => 'Website',
  498.             'Type' => 'Film Application Fee',
  499.             'StageName' => 'Closed',
  500.             'CloseDate' => (new \DateTime('now'))->format('Y-m-d'),
  501.             'Probability' => 100,
  502.             'DAF_retention__c' => '100%',
  503.             'Consent_to_be_identified__c' => 'Does NOT consent',
  504.             'Share_details__c' => 'DOESN\'T consent',
  505.             'Payment_Type__c' => 'Credit Card',
  506.             // 'Order_ID__c' => $orderDetails->getInvoiceNumber(),
  507.             'Order_ID__c' => 'MW'$orderDetails->getId(),
  508.             'Description' => $filmProject->getTitle(),
  509.             'Amount' => number_format(((float)$orderDetails->getTotal() / 100), 2'.'''),
  510.             // 'npe01__Amount_Written_Off__c' => 0,
  511.             // 'npe01__Amount_Outstanding__c' => 0,
  512.             'npsp__Acknowledgment_Status__c' => 'Do Not Acknowledge',
  513.             'CampaignId' =>  ($filmProject->getSalesforceId()) ? $filmProject->getSalesforceId() : '',
  514.         ];
  515.         
  516.         if ($ownerSfId) {
  517.             $data['npsp__Primary_Contact__c'] = $ownerSfId;
  518.         }
  519.         try {
  520.             $id $this->salesforceCrud->create(Constant::TRANSACTION_OBJ$data);
  521.         } catch (ClientException $e) {
  522.             $response $e->getResponse();
  523.             $responseBodyAsString $response->getBody()->getContents();
  524.             $this->throwExceptionMessage($responseBodyAsString);
  525.             var_dump($responseBodyAsString); exit();
  526.         }
  527.         return $id;
  528.     }
  529.     /**
  530.      * Create Donation Transaction
  531.      *
  532.      * @param Donation $donation
  533.      * @param OrderDetails $orderDetails
  534.      * @return void
  535.      */
  536.     public function createDonationTransaction(Donation $donation)
  537.     {
  538.         $orderDetails $donation->getOrderDetails();
  539.         $filmProject $donation->getFilmProject();
  540.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  541.         $accountName $orderBillingDetails->getOrganisation();
  542.         $user $orderDetails->getUser();
  543.         $salesforceDonatorId $user ? ($user->isAdmin() ? $this->createGuestContactFromOrderDetails($orderBillingDetails) : $user->getUserInformation()->getSalesforceId()) : $this->createGuestContactFromOrderDetails($orderBillingDetails);
  544.         if (empty($accountName)) {
  545.             $accountName sprintf('%s (%s) Household'$orderBillingDetails->getLastName(), $orderBillingDetails->getFirstName());
  546.         }
  547.         $ownerAccountId $this->createAccountWithOrderDetails($accountName$orderDetails$salesforceDonatorId); // Get owner Id
  548.         $data = [
  549.             'RecordTypeId' => Constant::SALESFORCE_TRANSACTION_TRANSACTION,
  550.             'Name' => 'Donation - '$filmProject->getTitle(),
  551.             'AccountId' =>  $ownerAccountId,
  552.             'npsp__Primary_Contact__c' => $salesforceDonatorId,
  553.             'LeadSource' => 'Website',
  554.             'Type' => 'Film Donation',
  555.             'StageName' => 'Closed',
  556.             'CloseDate' => (new \DateTime('now'))->format('Y-m-d'),
  557.             'Probability' => 100,
  558.             'DAF_retention__c' => '5%',
  559.             'Consent_to_be_identified__c' =>  ($donation->isIsOrganisationConsent()) ? 'Does consent' 'Does NOT consent',
  560.             'Share_details__c' => ($donation->isIsContactShared()) ? 'Does consent' 'DOESN\'T consent',
  561.             'Payment_Type__c' => 'Credit Card',
  562.             'Order_ID__c' => 'MW'$orderDetails->getId(),
  563.             'Description' => 'Donation for project: '$filmProject->getTitle(),
  564.             'Amount' => number_format(((float)($orderDetails->getTotal() - $donation->getSupportdaf()) / 100), 2'.'''),
  565.             // 'npe01__Amount_Written_Off__c' => 0,
  566.             // 'npe01__Amount_Outstanding__c' => 0,
  567.             'npsp__Acknowledgment_Status__c' => 'Do Not Acknowledge',
  568.             'CampaignId' => $filmProject->getSalesforceId(),
  569.             // 'WordPress_ID__c' => $filmProject->getWordpressId(),
  570.             // 'Wordpress_ID_from_2023__c' => $filmProject->getWordpressId(),
  571.         ];
  572.         // Check payment details
  573.         $paymentDetails $orderDetails->getPaymentDetails();
  574.         if ($paymentDetails) {
  575.             if ($paymentDetails->getType() == Constant::PAYMENT_EFT) {
  576.                 $data['Payment_Type__c'] = Constant::PAYMENT_EFT;
  577.             }
  578.         }
  579.         // Change close date
  580.         if ($orderDate $orderDetails->getCreatedAt()) {
  581.             $data['CloseDate'] = $orderDate->format('Y-m-d');
  582.         }
  583.         try {
  584.             $id $this->salesforceCrud->create(Constant::TRANSACTION_OBJ$data);
  585.         } catch (ClientException $e) {
  586.             $response $e->getResponse();
  587.             $responseBodyAsString $response->getBody()->getContents();
  588.             $this->throwExceptionMessage($responseBodyAsString);
  589.             var_dump($responseBodyAsString); exit();
  590.         }
  591.     
  592.         return $id;
  593.     }
  594.      /**
  595.      * Create DAF Donation Transaction
  596.      *
  597.      * @param Donation $donation
  598.      * @param OrderDetails $orderDetails
  599.      * @return string
  600.      */
  601.     public function createDafDonationTransaction(Donation $donation$popUpSalesforceId null)
  602.     {
  603.         $orderDetails $donation->getOrderDetails();
  604.         $user $orderDetails->getUser();
  605.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  606.         $accountName $orderBillingDetails->getOrganisation();
  607.         
  608.         $salesforceDonatorId null;
  609.         if ($user) { 
  610.             $salesforceDonatorId $user->getUserInformation()->getSalesforceId();
  611.         } else { // GUEST
  612.             $salesforceDonatorId $this->createGuestContactFromOrderDetails($orderBillingDetails);
  613.         }
  614.         if (empty($accountName)) {
  615.             $accountName sprintf('%s (%s) Household'$orderBillingDetails->getLastName(), $orderBillingDetails->getFirstName());
  616.         }
  617.         $ownerAccountId $this->createAccountWithOrderDetails($accountName$orderDetails$salesforceDonatorId); // Get owner Id
  618.         $data = [
  619.             'RecordTypeId' => Constant::SALESFORCE_TRANSACTION_TRANSACTION,
  620.             'Name' => 'Donation - Support Documentary Australia',
  621.             'AccountId' =>  $ownerAccountId,
  622.             'npsp__Primary_Contact__c' => $salesforceDonatorId,
  623.             'LeadSource' => 'Website',
  624.             'Type' => 'Donation',
  625.             'StageName' => 'Closed',
  626.             'CloseDate' => (new \DateTime('now'))->format('Y-m-d'),
  627.             'Probability' => 100,
  628.             'DAF_retention__c' => '100%',
  629.             'Consent_to_be_identified__c' =>  ($donation->isIsOrganisationConsent()) ? 'Does consent' 'Does NOT consent',
  630.             'Share_details__c' => ($donation->isIsContactShared()) ? 'Does consent' 'DOESN\'T consent',
  631.             'Payment_Type__c' => 'Credit Card',
  632.             'Order_ID__c' => 'MW'$orderDetails->getId(),
  633.             'Description' => 'Support Documentary Australia',
  634.             'Wordpress_ID_from_2023__c' => '35040'// Latest Support Documentary Australia Project
  635.             'Amount' => number_format(((float)$donation->getSupportdaf() / 100), 2'.'''),
  636.             // 'npe01__Amount_Written_Off__c' => 0,
  637.             // 'npe01__Amount_Outstanding__c' => 0,
  638.             'npsp__Acknowledgment_Status__c' => 'Do Not Acknowledge',
  639.         ];
  640.         if (!$popUpSalesforceId) {
  641.             if ($donation->getFilmProject()) {
  642.                 $filmProject $donation->getFilmProject();
  643.                 $data['CampaignId'] = $filmProject->getSalesforceId();
  644.                 if ($filmProject->isIsDafCore() && $filmProject->isIsDafProgram()) {
  645.                     $data['Name'] = 'Donation - '$filmProject->getTitle();
  646.                     $data['Description'] = 'Donation - '$filmProject->getTitle();
  647.                     $data['Wordpress_ID_from_2023__c'] = $filmProject->getWordpressId();
  648.                     $data['Amount'] = number_format(((float)$orderDetails->getTotal() / 100), 2'.''');
  649.                 }
  650.             }
  651.         } else {
  652.             $data['CampaignId'] = $popUpSalesforceId;
  653.             $data['Wordpress_ID_from_2023__c'] = '17135'// hardcoded latest popup filmproject
  654.             $data['Name'] = 'Donation - Documentary Australia\'s core operations_POP-UP';
  655.         }
  656.         // Check payment details
  657.         $paymentDetails $orderDetails->getPaymentDetails();
  658.         if ($paymentDetails) {
  659.             if ($paymentDetails->getType() == Constant::PAYMENT_EFT) {
  660.                 $data['Payment_Type__c'] = Constant::PAYMENT_EFT;
  661.             }
  662.         }
  663.         // Change close date
  664.         if ($orderDate $orderDetails->getCreatedAt()) {
  665.             $data['CloseDate'] = $orderDate->format('Y-m-d');
  666.         }
  667.         try {
  668.             $id $this->salesforceCrud->create(Constant::TRANSACTION_OBJ$data);
  669.         } catch (ClientException $e) {
  670.             $response $e->getResponse();
  671.             $responseBodyAsString $response->getBody()->getContents();
  672.             $this->throwExceptionMessage($responseBodyAsString);
  673.             var_dump($responseBodyAsString); exit();
  674.         }
  675.     
  676.         return $id;
  677.     }
  678.     /**
  679.      * Updated transaction details
  680.      *
  681.      * @param OrderDetails $orderDetails
  682.      * @return void
  683.      */
  684.     public function updateTransaction(OrderDetails $orderDetails)
  685.     {
  686.         $salesforceId $orderDetails->getSalesforceId();
  687.         if (empty($salesforceId)) {
  688.             return;
  689.         }
  690.         $updatedData = [
  691.             'Amount' => $orderDetails->getTotal() / 100,
  692.         ];
  693.         if ($donation $orderDetails->getDonation()) {
  694.             $filmProject $donation->getFilmProject();
  695.             $updatedData = [
  696.                 'Name' => 'Donation - '$filmProject->getTitle(),
  697.                 'Amount' => $orderDetails->getTotal() / 100,
  698.                 'CampaignId' => $filmProject->getSalesforceId(),
  699.                 'StageName' => 'Closed',
  700.                 'npsp__Acknowledgment_Status__c' => 'Do Not Acknowledge',
  701.             ];
  702.     
  703.         }
  704.         try {
  705.             $statusCode =  $this->salesforceCrud->update(Constant::TRANSACTION_OBJ$salesforceId$updatedData);
  706.         } catch (ClientException $e) {
  707.             $response $e->getResponse();
  708.             $responseBodyAsString $response->getBody()->getContents();
  709.             $this->throwExceptionMessage("Opportunity object on Salesforce is not found. Please contact admin for more information.");
  710.             var_dump($responseBodyAsString); exit();
  711.         }
  712.         // Update payment amount as well
  713.         $paymentId $this->getPaymentByTransactionId($salesforceId);
  714.         if ($paymentId) {
  715.             $this->updatePaymentAmountReceived($paymentId$orderDetails->getTotal() / 100);
  716.         }
  717.     }
  718.      /**
  719.      * Updated campaign object to be refunded
  720.      *
  721.      * @param OrderDetails $orderDetails
  722.      * @return void
  723.      */
  724.     public function refundTransaction(OrderDetails $orderDetails)
  725.     {
  726.         $salesforceId $orderDetails->getSalesforceId();
  727.         if (empty($salesforceId)) {
  728.             return;
  729.         }
  730.         $updatedData = [
  731.             'Amount' => 0,
  732.             'Refunded__c' => 1,
  733.         ];
  734.         try {
  735.             $statusCode =  $this->salesforceCrud->update(Constant::TRANSACTION_OBJ$salesforceId$updatedData);
  736.         } catch (ClientException $e) {
  737.             $response $e->getResponse();
  738.             $responseBodyAsString $response->getBody()->getContents();
  739.             $this->throwExceptionMessage($responseBodyAsString);
  740.             var_dump($responseBodyAsString); exit();
  741.         }
  742.         // Update payment amount as well
  743.         $paymentId $this->getPaymentByTransactionId($salesforceId);
  744.         if ($paymentId) {
  745.             $this->updatePaymentAmountRefund($paymentId);
  746.         }
  747.     }
  748.     /**
  749.      * Updated campaign object to be refunded
  750.      *
  751.      * @param OrderDetails $orderDetails
  752.      * @return void
  753.      */
  754.     public function refundDafSupportTransaction(Donation $donation)
  755.     {
  756.         $salesforceId $donation->getSupportDafSalesforce();
  757.         if (empty($salesforceId)) {
  758.             return;
  759.         }
  760.         $updatedData = [
  761.             'Amount' => 0,
  762.             'Refunded__c' => 1,
  763.         ];
  764.         try {
  765.             $statusCode =  $this->salesforceCrud->update(Constant::TRANSACTION_OBJ$salesforceId$updatedData);
  766.         } catch (ClientException $e) {
  767.             $response $e->getResponse();
  768.             $responseBodyAsString $response->getBody()->getContents();
  769.             $this->throwExceptionMessage($responseBodyAsString);
  770.             var_dump($responseBodyAsString); exit();
  771.         }
  772.         // Update payment amount as well
  773.         $paymentId $this->getPaymentByTransactionId($salesforceId);
  774.         if ($paymentId) {
  775.             $this->updatePaymentAmountRefund($paymentId);
  776.         }
  777.     }
  778.     /**
  779.      * get campaign with wordpress ID
  780.      *
  781.      * @param User $user
  782.      * @return void
  783.      */
  784.     public function getCampaignByWordpressId(int $id)
  785.     {
  786.         $query 'SELECT Id FROM Campaign WHERE Wordpress_ID__c = \''$id .'\'';
  787.         $result $this->salesforceCrud->query($query);
  788.         if ($result['totalSize'] <= 0) {
  789.             return false;
  790.         }
  791.         $id $result['records'][0]['Id'];
  792.         return $id;
  793.     }
  794.     /**
  795.      * Create campaign object from film project entity
  796.      *
  797.      * @param FilmProject $filmProject
  798.      * @return void|string
  799.      */
  800.     public function updateCampaignByPayload($salesforceId, array $payLoad)
  801.     {
  802.         try {
  803.             $id $this->salesforceCrud->update(Constant::CAMPAIGN_OBJ$salesforceId$payLoad); 
  804.         } catch (ClientException $e) {
  805.             $response $e->getResponse();
  806.             $responseBodyAsString $response->getBody()->getContents();
  807.             var_dump($salesforceId .' is having error'); exit();
  808.             $this->throwExceptionMessage($responseBodyAsString);
  809.             return null;
  810.         }
  811.     
  812.         return $id;
  813.     }
  814.     /**
  815.      * get contact ID if exists, return false if doesnt exists
  816.      *
  817.      * @param User $user
  818.      * @return string|void
  819.      */
  820.     public function getContactBySalesforceId(string $id)
  821.     {
  822.         $query 'SELECT Id FROM Contact WHERE Id = \''$id .'\'';
  823.         $result $this->salesforceCrud->query($query);
  824.         if ($result['totalSize'] <= 0) {
  825.             return false;
  826.         }
  827.         $id $result['records'][0]['Id'];
  828.         return $id;
  829.     }
  830.     /**
  831.      * Get Payment ID by Transaction ID
  832.      *
  833.      * @param string $id
  834.      * @return false|String
  835.      */
  836.     public function getPaymentByTransactionId(string $id
  837.     {
  838.         $query 'SELECT Id FROM npe01__OppPayment__c WHERE npe01__Opportunity__c = \''$id .'\'';
  839.         try {
  840.             $result $this->salesforceCrud->query($query);
  841.         } catch (ClientException $e) {
  842.             return false;
  843.         }
  844.         if ($result['totalSize'] <= 0) {
  845.             return false;
  846.         }
  847.         $id $result['records'][0]['Id'];
  848.         return $id;
  849.     }
  850.     /**
  851.      * Update campaign object to be approved
  852.      *
  853.      * @param String $salesforceId
  854.      * @return void
  855.      */
  856.     public function updatePaymentAmountReceived(String $salesforceId$amount
  857.     {
  858.         $updatedData = [
  859.             'npe01__Payment_Amount__c' => $amount,
  860.         ];
  861.         $statusCode =  $this->salesforceCrud->update('npe01__OppPayment__c'$salesforceId$updatedData);
  862.     }
  863.     /**
  864.      * Update campaign object to be approved
  865.      *
  866.      * @param String $salesforceId
  867.      * @return void
  868.      */
  869.     public function updatePaymentAmountRefund(String $salesforceId
  870.     {
  871.         $updatedData = [
  872.             'npe01__Payment_Amount__c' => number_format(02'.'''),
  873.         ];
  874.         $statusCode =  $this->salesforceCrud->update('npe01__OppPayment__c'$salesforceId$updatedData);
  875.     }
  876.     public function getSalesforceCrud() {
  877.         return $this->salesforceCrud;
  878.     }
  879.     public function deleteContact(User $user)
  880.     {
  881.         $userInformation $user->getUserInformation();
  882.         $id $userInformation->getSalesforceId();
  883.         try {
  884.             $this->salesforceCrud->delete(Constant::CONTACT_OBJ$id);  #returns id
  885.         } catch(Exception $e) {
  886.             return;
  887.         }
  888.     }
  889.     public function replaceWordpressIds(FilmProject $filmProject
  890.     {
  891.         $salesforceId $filmProject->getSalesforceId();
  892.         $updatedData = [
  893.             'Wordpress_ID__c' => $filmProject->getOldWordpressId() ? $filmProject->getOldWordpressId() : '',
  894.             // 'Wordpress_ID_2023__c' => $filmProject->getWordpressId() ? $filmProject->getWordpressId() : '',
  895.         ];
  896.         $statusCode =  $this->salesforceCrud->update(Constant::CAMPAIGN_OBJ$salesforceId$updatedData);
  897.     }
  898.     public function updateProgressReport(FilmProjectProgressReport $progressReport) {
  899.         $filmProject $progressReport->getFilmProject();
  900.         $salesforceId $filmProject->getSalesforceId();
  901.         $updatedData =  $this->salesforceObjectConverter->convertProgressReportToCampaign($progressReport);
  902.        
  903.         $statusCode =  $this->salesforceCrud->update(Constant::CAMPAIGN_OBJ$salesforceId$updatedData);
  904.     }
  905.     /**
  906.      * Creates content version data to upload file to Salesforce
  907.      */
  908.     public function createContentVersionData(FilmProjectProgressReportFile $progressReportFile) {
  909.         $data = [
  910.             'Title' => $progressReportFile->getFileName(),
  911.             'PathOnClient' => $progressReportFile->getFileName(),
  912.             'VersionData' => Constant::LOCALHOST_URL '/uploads/progress_reports/'$progressReportFile->getFileName(),
  913.         ];
  914.         
  915.         $id $this->salesforceCrud->create('ContentVersion'$data);  #returns id
  916.         return $id;
  917.     }
  918.     /**
  919.      * Gets Document ID from uploaded ContentVersionData
  920.      */
  921.     public function getDocumentIdFromContentVersion(String $contentVersionId) {
  922.         $query 'SELECT ContentDocumentId FROM ContentVersion WHERE Id = \''$contentVersionId .'\'';
  923.         try {
  924.             $result $this->salesforceCrud->query($query);
  925.         } catch (ClientException $e) {
  926.             return false;
  927.         }
  928.         if ($result['totalSize'] <= 0) {
  929.             return false;
  930.         }
  931.         $id $result['records'][0]['ContentDocumentId'];
  932.         return $id;
  933.     }
  934.     /**
  935.      * Links between the uplaoded file and campaign ID on Salesforce end
  936.      */
  937.     public function createDocumentLink(String $contentDocumentIdString $campaignId) {
  938.         $data = [
  939.             'ContentDocumentId' => $contentDocumentId,
  940.             'LinkedEntityId' => $campaignId,
  941.             'ShareType' => 'V'// Viewer
  942.         ];
  943.         
  944.         $id $this->salesforceCrud->create('ContentDocumentLink'$data);  #returns id
  945.     }
  946. }