src/Service/Xero/ContactService.php line 25

Open in your IDE?
  1. <?php
  2. // src/Service/UserService.php
  3. namespace App\Service\Xero;
  4. use App\Entity\FilmProject;
  5. use App\Entity\OrderDetails;
  6. use App\Entity\User;
  7. use App\Authenticator\XeroAuthenticator;
  8. use App\Repository\UserRepository;
  9. use App\Service\Xero\XeroService;
  10. use Exception;
  11. use XeroAPI\XeroPHP\AccountingObjectSerializer;
  12. use XeroAPI\XeroPHP\Models\Accounting\Contact;
  13. use XeroAPI\XeroPHP\Models\Accounting\ContactPerson;
  14. use XeroAPI\XeroPHP\Models\Accounting\Contacts;
  15. use XeroAPI\XeroPHP\ApiException;
  16. use XeroAPI\XeroPHP\Models\Accounting\Address;
  17. final class ContactService extends XeroService
  18. {
  19.     private $userRepository;
  20.     public function __construct(XeroAuthenticator $xeroAuthenticatorUserRepository $userRepository)
  21.     {        
  22.         parent::__construct($xeroAuthenticator);
  23.         $this->userRepository $userRepository;
  24.     }
  25.     /**
  26.      * Create Xero contact 
  27.      *
  28.      * @param User $user
  29.      * @return string
  30.      */
  31.     public function createContact(User $user): string 
  32.     {
  33.          // Check if contact is already registered in the system
  34.         $xeroID $this->getContactByUser($user);
  35.         if (!empty($xeroID)) {
  36.             return $xeroID;
  37.         }
  38.         $contact = new Contact;
  39.         $contact->setName($user->getFirstName() . ' ' $user->getLastName())
  40.             ->setFirstName($user->getFirstName())
  41.             ->setLastName($user->getLastName())
  42.             ->setEmailAddress($user->getEmail())
  43.         ;
  44.         if ($user->getUserAddress()) {
  45.             $userAddress $user->getUserAddress();
  46.             
  47.             $address = new Address();
  48.             $address->setAddressType(Address::ADDRESS_TYPE_STREET);
  49.             if ($userAddress->getStreet()) $address->setAddressLine1($userAddress->getStreet());
  50.             if ($userAddress->getCity()) $address->setCity($userAddress->getCity());
  51.             if ($userAddress->getState()) $address->setRegion($userAddress->getState());
  52.             if ($userAddress->getPostcode()) $address->setPostalCode($userAddress->getPostcode());
  53.             if ($userAddress->getCountry()) $address->setCountry($userAddress->getCountry());
  54.             $arr_addresses = [];
  55.             array_push($arr_addresses$address);
  56.             $contact->setAddresses($arr_addresses);
  57.         }
  58.         $arr_contacts = [];
  59.         array_push($arr_contacts$contact);
  60.         $contacts = new Contacts;
  61.         $contacts->setContacts($arr_contacts);
  62.         try {
  63.             $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  64.         } catch(ApiException $e) {
  65.             $this->throwXeroException($e);
  66.         } 
  67.         if ($apiResponse[0]['has_validation_errors']) {
  68.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  69.         }
  70.         return $apiResponse[0]['contact_id'];
  71.     }
  72.     public function findContactByprojectName(FilmProject $filmProject): string null
  73.     {
  74.         $fullName $filmProject->getTitle();
  75.         /** This represents paramater needed for Xero getContacts */
  76.         $modifiedSince = new \DateTime('2010-01-01');
  77.         $where 'ContactStatus=="' Contact::CONTACT_STATUS_ACTIVE '"';
  78.         $order "Name ASC";
  79.         $page 1;
  80.         $searchTerm $fullName// since xero has contactName as its unique name
  81.         $includeArchived true;
  82.         $summaryOnly true;
  83.         try {
  84.             $contacts $this->xeroAccountingManager->getContacts($this->xeroTenantId$modifiedSince$where$ordernull$page$includeArchived$summaryOnly$searchTerm);
  85.         } catch(ApiException $e) {
  86.         dd($e);
  87.             $this->throwXeroException($e);
  88.         } 
  89.         if(count($contacts) > 0) {
  90.             return $contacts[0]['contact_id'];
  91.         }
  92.         return null;
  93.     }
  94.     /**
  95.      * Create Xero contact 
  96.      *
  97.      * @param User $user
  98.      * @return string
  99.      */
  100.     public function createContactByProjectName(FilmProject $filmProject): string 
  101.     {
  102.         $contact = new Contact;
  103.         $user $filmProject->getOwner();
  104.         $contact->setName($filmProject->getTitle()) // Unique name here
  105.             ->setFirstName($user->getFirstName())
  106.             ->setLastName($user->getLastName())
  107.             ->setEmailAddress($user->getEmail())
  108.         ;
  109.         if ($user->getUserAddress()) {
  110.             $userAddress $user->getUserAddress();
  111.             
  112.             $address = new Address();
  113.             $address->setAddressType(Address::ADDRESS_TYPE_STREET);
  114.             if ($userAddress->getStreet()) $address->setAddressLine1($userAddress->getStreet());
  115.             if ($userAddress->getCity()) $address->setCity($userAddress->getCity());
  116.             if ($userAddress->getState()) $address->setRegion($userAddress->getState());
  117.             if ($userAddress->getPostcode()) $address->setPostalCode($userAddress->getPostcode());
  118.             if ($userAddress->getCountry()) $address->setCountry($userAddress->getCountry());
  119.             $arr_addresses = [];
  120.             array_push($arr_addresses$address);
  121.             $contact->setAddresses($arr_addresses);
  122.         }
  123.         $arr_contacts = [];
  124.         array_push($arr_contacts$contact);
  125.         $contacts = new Contacts;
  126.         $contacts->setContacts($arr_contacts);
  127.         try {
  128.             $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  129.         } catch(ApiException $e) {
  130.             $this->throwXeroException($e);
  131.         } 
  132.         if ($apiResponse[0]['has_validation_errors']) {
  133.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  134.         }
  135.         return $apiResponse[0]['contact_id'];
  136.     }
  137.     /**
  138.      * Update contact
  139.      *
  140.      * @param User $user
  141.      * @return void
  142.      */
  143.     public function updateContact(User $user)
  144.     {
  145.         $userInformation $user->getUserInformation();
  146.         $userAddress $user->getUserAddress();
  147.         $xeroContactId $userInformation->getXeroId();
  148.         $arr_addresses = [];
  149.         $address = (new Address())
  150.             ->setAddressType(Address::ADDRESS_TYPE_STREET)
  151.             ->setAddressLine1($userAddress->getStreet())
  152.             ->setCity($userAddress->getCity())
  153.             ->setPostalCode($userAddress->getPostcode())
  154.         ;
  155.         array_push($arr_addresses$address);
  156.         $contact = new Contact();
  157.         $contact
  158.             ->setName($user->getFirstName() . ' ' $user->getLastName())
  159.             ->setFirstName($user->getFirstName())
  160.             ->setLastName($user->getLastName())
  161.             ->setContactID($xeroContactId)
  162.             ->setAddresses($arr_addresses)
  163.         ;
  164.         $arr_contacts = [];
  165.         array_push($arr_contacts$contact);
  166.         $contacts = new Contacts;
  167.         $contacts->setContacts($arr_contacts);
  168.         try {
  169.             $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  170.         } catch(ApiException $e) {
  171.             $this->throwXeroException($e);
  172.         } 
  173.         if ($apiResponse[0]['has_validation_errors']) {
  174.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  175.         }
  176.         
  177.         return $apiResponse[0]['contact_id'];
  178.     }
  179.     /**
  180.      * Get contacts by email
  181.      *
  182.      * @param [type] $fullname
  183.      * @return string
  184.      */
  185.     public function getContactByUser(User $user): ?string
  186.     {
  187.         $fullName $user->getFirstName() . ' ' $user->getLastName();
  188.         /** This represents paramater needed for Xero getContacts */
  189.         $modifiedSince = new \DateTime('2010-01-01');
  190.         $where 'ContactStatus=="' Contact::CONTACT_STATUS_ACTIVE '"';
  191.         $order "Name ASC";
  192.         $page 1;
  193.         $searchTerm $fullName// since xero has contactName as its unique name
  194.         $includeArchived true;
  195.         $summaryOnly true;
  196.         $isExistContact false;
  197.         try {
  198.             $contacts $this->xeroAccountingManager->getContacts($this->xeroTenantId$modifiedSince$where$ordernull$page$includeArchived$summaryOnly$searchTerm);
  199.         } catch(ApiException $e) {
  200.             $this->throwXeroException($e);
  201.         } 
  202.         if(count($contacts) > 0$isExistContact true;
  203.         foreach ($contacts as $contact) {
  204.             if (strtolower($contact['email_address']) == strtolower($user->getEmailAddress())) {
  205.                 return $contact['contact_id'];
  206.             }
  207.         }
  208.         if ($isExistContact) { // If contact found but no email address found in that contact, add it as an additional person
  209.             $xeroContactId $contacts[0]['contact_id']; // Get the first contact details ID
  210.             return $this->updateContactWithAdditionalPersonDetails($user$xeroContactId);
  211.         }
  212.         return null;
  213.     }
  214.     /**
  215.      * Get contacts by email
  216.      *
  217.      * @param [type] $fullname
  218.      * @return string
  219.      */
  220.     public function getContactByEmail(string $email): ?string
  221.     {
  222.         /** This represents paramater needed for Xero getContacts */
  223.         $modifiedSince = new \DateTime('2010-01-01');
  224.         $where 'ContactStatus=="' Contact::CONTACT_STATUS_ACTIVE '"';
  225.         $order "Name ASC";
  226.         $page 1;
  227.         $searchTerm $email;
  228.         $includeArchived true;
  229.         $summaryOnly true;
  230.         $contacts $this->xeroAccountingManager->getContacts($this->xeroTenantId$modifiedSince$where$ordernull$page$includeArchived$summaryOnly$searchTerm);
  231.         foreach ($contacts as $contact) {
  232.             if ($contact['email_address'] == $email) {
  233.                 return $contact['contact_id'];
  234.             }
  235.         }
  236.         return null;
  237.     }
  238.     /**
  239.      * Get contacts by id
  240.      *
  241.      * @param [type] $fullname
  242.      * @return obj
  243.      */
  244.     public function getContactById(string $contactId)
  245.     {
  246.         try {
  247.             $contacts $this->xeroAccountingManager->getContact($this->xeroTenantId$contactId);
  248.         }
  249.         catch (Exception $e) {
  250.             $this->throwExceptionMessage($e->getMessage());
  251.         }
  252.         
  253.         if ($contacts) {
  254.             return $contacts[0];
  255.         }
  256.         return null;
  257.     }
  258.     /**
  259.      * Get contacts by name
  260.      *
  261.      * @param [type] $fullname
  262.      * @return string
  263.      */
  264.     public function getContactByOrderDetails(OrderDetails $orderDetails): ?string
  265.     {
  266.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  267.         $user $this->userRepository->findOneBy(['email' => $orderBillingDetails->getEmailAddress()]);
  268.         $fullName $orderBillingDetails->getFirstName() .' '$orderBillingDetails->getLastName();
  269.         // TODO: ENABLED when client agree to use the same ID for the same contact integrated with the system
  270.         // if ($user) {
  271.             // $fullName = $user->getFirstName() .' '. $user->getLastName() . ' - ' . $user->getId();
  272.         //     $userInformation = $user->getUserInformation();
  273.         //     return $userInformation->getXeroId();
  274.         // }             
  275.         /** This represents paramater needed for Xero getContacts */
  276.         $modifiedSince = new \DateTime('2020-01-01');
  277.         $where 'ContactStatus=="' Contact::CONTACT_STATUS_ACTIVE '"';
  278.         $order "Name ASC";
  279.         $page 1;
  280.         // $searchTerm = $fullName;
  281.         $searchTerm =  $orderBillingDetails->getEmailAddress();
  282.         $includeArchived true;
  283.         $summaryOnly true;
  284.         try {
  285.             $contacts $this->xeroAccountingManager->getContacts($this->xeroTenantId$modifiedSince$where$ordernull$page$includeArchived$summaryOnly$searchTerm);
  286.         } catch(ApiException $e) {
  287.             $this->throwXeroException($e);
  288.         } 
  289.         foreach ($contacts as $contact) {
  290.             // if (strtolower($contact['name']) == strtolower($fullName)) {
  291.             if (str_contains(strtolower($contact['name']),strtolower($fullName) )) {
  292.                 return $contact['contact_id'];
  293.             }
  294.         }
  295.         return null;
  296.     }
  297.     
  298.     /**
  299.      * Create Xero contact 
  300.      *
  301.      * @param User $user
  302.      * @return string
  303.      */
  304.     public function createContactByOrderDetails(OrderDetails $orderDetails): string 
  305.     {
  306.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  307.         $contact = new Contact;
  308.         $contact->setName($orderBillingDetails->getFirstName() . ' ' $orderBillingDetails->getLastName() . ' - '$orderDetails->getId())
  309.                 ->setFirstName($orderBillingDetails->getFirstName())
  310.                 ->setLastName($orderBillingDetails->getLastName())
  311.                 ->setEmailAddress($orderBillingDetails->getEmailAddress());
  312.         $address = new Address();
  313.         $address->setAddressType(Address::ADDRESS_TYPE_POBOX);
  314.         if ($orderBillingDetails->getStreet()) $address->setAddressLine1($orderBillingDetails->getStreet());
  315.         if ($orderBillingDetails->getSuburb()) $address->setCity($orderBillingDetails->getSuburb());
  316.         if ($orderBillingDetails->getState()) $address->setRegion($orderBillingDetails->getState());
  317.         if ($orderBillingDetails->getPostcode()) $address->setPostalCode($orderBillingDetails->getPostcode());
  318.         if ($orderBillingDetails->getCountry()) $address->setCountry($orderBillingDetails->getCountry());
  319.         $arr_addresses = [];
  320.         array_push($arr_addresses$address);
  321.         $contact->setAddresses($arr_addresses);
  322.         $arr_contacts = [];
  323.         array_push($arr_contacts$contact);
  324.         $contacts = new Contacts;
  325.         $contacts->setContacts($arr_contacts);
  326.         try {
  327.             $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  328.         } catch(ApiException $e) {
  329.             $this->throwXeroException($e);
  330.         } 
  331.         if ($apiResponse[0]['has_validation_errors']) {
  332.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  333.         }
  334.         return $apiResponse[0]['contact_id'];
  335.     }
  336.     /**
  337.      * Create Xero contact 
  338.      *
  339.      * @param User $user
  340.      * @return string
  341.      */
  342.     public function createGuestContactByOrderDetails(OrderDetails $orderDetails): string 
  343.     {
  344.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  345.         $contact = new Contact;
  346.         $contact->setName($orderBillingDetails->getFirstName() . ' ' $orderBillingDetails->getLastName())
  347.                 ->setFirstName($orderBillingDetails->getFirstName())
  348.                 ->setLastName($orderBillingDetails->getLastName())
  349.                 ->setEmailAddress($orderBillingDetails->getEmailAddress());
  350.         $arr_contacts = [];
  351.         array_push($arr_contacts$contact);
  352.         $contacts = new Contacts;
  353.         $contacts->setContacts($arr_contacts);
  354.         try {
  355.             $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  356.         } catch(ApiException $e) {
  357.             $this->throwXeroException($e);
  358.         } 
  359.         if ($apiResponse[0]['has_validation_errors']) {
  360.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  361.         }
  362.         return $apiResponse[0]['contact_id'];
  363.     }
  364.     
  365.     /**
  366.      * Update Xero contact details
  367.      *
  368.      * @param OrderDetails $orderDetails
  369.      * @param [type] $xeroContactId
  370.      * @return void
  371.      */
  372.     public function updateContactByOrderDetails(OrderDetails $orderDetails$xeroContactId)
  373.     {
  374.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  375.         $contact = new Contact();
  376.         $contact
  377.             // ->setName($orderBillingDetails->getFirstName() . ' ' . $orderBillingDetails->getLastName())
  378.             ->setFirstName($orderBillingDetails->getFirstName())
  379.             ->setLastName($orderBillingDetails->getLastName())
  380.             ->setEmailAddress($orderBillingDetails->getEmailAddress())
  381.             ->setContactID($xeroContactId)
  382.             // TODO: set other fields such as address
  383.         ;
  384.         $address = new Address();
  385.         $address->setAddressType(Address::ADDRESS_TYPE_POBOX);
  386.         if ($orderBillingDetails->getStreet()) $address->setAddressLine1($orderBillingDetails->getStreet());
  387.         if ($orderBillingDetails->getSuburb()) $address->setCity($orderBillingDetails->getSuburb());
  388.         if ($orderBillingDetails->getState()) $address->setRegion($orderBillingDetails->getState());
  389.         if ($orderBillingDetails->getPostcode()) $address->setPostalCode($orderBillingDetails->getPostcode());
  390.         if ($orderBillingDetails->getCountry()) $address->setCountry($orderBillingDetails->getCountry());
  391.         $arr_addresses = [];
  392.         array_push($arr_addresses$address);
  393.         $contact->setAddresses($arr_addresses);
  394.         $arr_contacts = [];
  395.         array_push($arr_contacts$contact);
  396.         $contacts = new Contacts;
  397.         $contacts->setContacts($arr_contacts);
  398.         $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  399.         if ($apiResponse[0]['has_validation_errors']) {
  400.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  401.         }
  402.         
  403.         return $apiResponse[0]['contact_id'];
  404.     }
  405.     
  406.     /**
  407.      * Check if contact exists on current XERO contact Id
  408.      *
  409.      * @param [type] $contactId
  410.      * @return void
  411.      */
  412.     public function checkContactExists($xeroContactId) {
  413.         $isExist false;
  414.         try {
  415.             $apiResponse $this->xeroAccountingManager->getContact($this->xeroTenantId$xeroContactId);
  416.         } catch (ApiException $e) {
  417.             return $isExist;
  418.         }
  419.         if (!$apiResponse[0]['HasValidationErrors']) {
  420.             $isExist true;
  421.         }
  422.     
  423.         return $isExist;
  424.     }
  425.     
  426.     /**
  427.      * Update contact
  428.      *
  429.      * @param OrderDetails $orderDetails
  430.      * @param string $xeroContactId
  431.      * @return void
  432.      */
  433.     public function updateContactById(OrderDetails $orderDetailsstring $xeroContactId)
  434.     {
  435.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  436.         $contact = new Contact();
  437.         $contact
  438.             ->setFirstName($orderBillingDetails->getFirstName())
  439.             ->setLastName($orderBillingDetails->getLastName())
  440.         ;
  441.         $address = new Address();
  442.         $address->setAddressType(Address::ADDRESS_TYPE_POBOX);
  443.         if ($orderBillingDetails->getStreet()) $address->setAddressLine1($orderBillingDetails->getStreet());
  444.         if ($orderBillingDetails->getSuburb()) $address->setCity($orderBillingDetails->getSuburb());
  445.         if ($orderBillingDetails->getState()) $address->setRegion($orderBillingDetails->getState());
  446.         if ($orderBillingDetails->getPostcode()) $address->setPostalCode($orderBillingDetails->getPostcode());
  447.         if ($orderBillingDetails->getCountry()) $address->setCountry($orderBillingDetails->getCountry());
  448.         $arr_addresses = [];
  449.         array_push($arr_addresses$address);
  450.         $contact->setAddresses($arr_addresses);
  451.         $arr_contacts = [];
  452.         array_push($arr_contacts$contact);
  453.         $contacts = new Contacts;
  454.         $contacts->setContacts($arr_contacts);
  455.         try {
  456.             $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  457.         } catch(ApiException $e) {
  458.             $this->throwXeroException($e);
  459.         } 
  460.         if ($apiResponse[0]['has_validation_errors']) {
  461.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  462.         }
  463.         
  464.         return $apiResponse[0]['contact_id'];
  465.     }
  466.     /**
  467.      * Get contacts by organisation name
  468.      *
  469.      * @param OrderDetails $orderDetails
  470.      * @return string
  471.      */
  472.     public function getContactOrganisationByOrderDetails(OrderDetails $orderDetails): ?string
  473.     {
  474.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  475.         $fullName $orderBillingDetails->getOrganisation();
  476.         /** This represents paramater needed for Xero getContacts */
  477.         $modifiedSince = new \DateTime('2020-01-01');
  478.         $where 'ContactStatus=="' Contact::CONTACT_STATUS_ACTIVE '"';
  479.         $order "Name ASC";
  480.         $page 1;
  481.         $searchTerm $fullName;
  482.         // $searchTerm =  $orderBillingDetails->getEmailAddress();
  483.         $includeArchived true;
  484.         $summaryOnly true;
  485.         // Set maximum length of a full name to 50
  486.         if (strlen($searchTerm) > 50) {
  487.             // Truncate the string to 50 characters
  488.             $searchTerm substr($searchTerm050);
  489.         }
  490.         try {
  491.             $contacts $this->xeroAccountingManager->getContacts($this->xeroTenantId$modifiedSince$where$ordernull$page$includeArchived$summaryOnly$searchTerm);
  492.         } catch(ApiException $e) {
  493.             $this->throwXeroException($e);
  494.         } 
  495.         foreach ($contacts as $contact) { // Make sure that the actual name is exactly the same as the search results
  496.             if (strtolower($contact['name']) == strtolower($fullName)) {
  497.                 return $contact['contact_id'];
  498.             }
  499.         }
  500.         return null;
  501.     }
  502.     /**
  503.      * Create Xero contact with organisation name 
  504.      *
  505.      * @param User $user
  506.      * @return string
  507.      */
  508.     public function createContactOrganisationByOrderDetails(OrderDetails $orderDetails): string 
  509.     {
  510.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  511.         $contact = new Contact;
  512.         $contact->setName($orderBillingDetails->getOrganisation())
  513.                 ->setFirstName($orderBillingDetails->getFirstName())
  514.                 ->setLastName($orderBillingDetails->getLastName())
  515.                 ->setEmailAddress($orderBillingDetails->getEmailAddress());
  516.         $address = new Address();
  517.         $address->setAddressType(Address::ADDRESS_TYPE_POBOX);
  518.         if ($orderBillingDetails->getStreet()) $address->setAddressLine1($orderBillingDetails->getStreet());
  519.         if ($orderBillingDetails->getSuburb()) $address->setCity($orderBillingDetails->getSuburb());
  520.         if ($orderBillingDetails->getState()) $address->setRegion($orderBillingDetails->getState());
  521.         if ($orderBillingDetails->getPostcode()) $address->setPostalCode($orderBillingDetails->getPostcode());
  522.         if ($orderBillingDetails->getCountry()) $address->setCountry($orderBillingDetails->getCountry());
  523.         $arr_contacts = [];
  524.         array_push($arr_contacts$contact);
  525.         $contacts = new Contacts;
  526.         $contacts->setContacts($arr_contacts);
  527.         try {
  528.             $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  529.         } catch(ApiException $e) {
  530.             $this->throwXeroException($e);
  531.         } 
  532.         if ($apiResponse[0]['has_validation_errors']) {
  533.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  534.         }
  535.         return $apiResponse[0]['contact_id'];
  536.     }
  537.     /**
  538.      * Gets all the additional persons from the contact based on XERO ID
  539.      *
  540.      * @param string $xeroID
  541.      * @return void|arr
  542.      */
  543.     private function getOrganisationAdditionalPersonByXeroId(string $xeroID)
  544.     {
  545.         $result = [];
  546.         $contact $this->getContactById($xeroID);
  547.         if (!empty($contact['contact_persons'])) {
  548.             return $contact['contact_persons'];
  549.         }
  550.         return $result;
  551.     }
  552.     private function updateContactWithAdditionalPersonDetails(User $user$xeroContactId
  553.     {
  554.         // Check if the order billing details already exists as one of the additional person arr
  555.         $additionalPersonsArr $this->getOrganisationAdditionalPersonByXeroId($xeroContactId);
  556.         $isExist false;
  557.         foreach ($additionalPersonsArr as $personArr) {
  558.             if ($user->getFirstName() == $personArr->getFirstName() && $user->getLastName() == $personArr->getLastName() && $user->getEmailAddress() == $personArr->getEmailAddress()) {
  559.                 $isExist true;
  560.                 break;
  561.             }
  562.         }
  563.         if ($isExist) { // If alreadt exist, dont update anything
  564.             return null;
  565.         }
  566.         $person = new ContactPerson;
  567.         $person
  568.             ->setFirstName($user->getFirstName())
  569.             ->setLastName($user->getLastName())
  570.             ->setEmailAddress($user->getEmailAddress())
  571.             ->setIncludeInEmails(false)
  572.         ;
  573.         array_push($additionalPersonsArr$person);
  574.         $contact = new Contact;
  575.         $contact
  576.             ->setContactPersons($additionalPersonsArr)
  577.         ;
  578.         $arr_contacts = [];
  579.         array_push($arr_contacts$contact);
  580.         $contacts = new Contacts;
  581.         $contacts->setContacts($arr_contacts);
  582.         // Update the contact with additional person data
  583.         try {
  584.             $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  585.         } catch(ApiException $e) {
  586.             $this->throwXeroException($e);
  587.         } 
  588.         if ($apiResponse[0]['has_validation_errors']) {
  589.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  590.         }
  591.         
  592.         return $apiResponse[0]['contact_id'];
  593.     }
  594.     /**
  595.      * Adds a new person as an additional person in the contact
  596.      *
  597.      * @param OrderDetails $orderDetails
  598.      * @param [type] $xeroContactId
  599.      * @return void
  600.      */
  601.     public function updateOrganisationWithAdditionalPersonByOrderDetails(OrderDetails $orderDetails$xeroContactId)
  602.     {
  603.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  604.         // Check if the order billing details already exists as one of the additional person arr
  605.         $additionalPersonsArr $this->getOrganisationAdditionalPersonByXeroId($xeroContactId);
  606.         $isExist false;
  607.         foreach ($additionalPersonsArr as $personArr) {
  608.             if ($orderBillingDetails->getFirstName() == $personArr->getFirstName() && $orderBillingDetails->getLastName() == $personArr->getLastName() && $orderBillingDetails->getEmailAddress() == $personArr->getEmailAddress()) {
  609.                 $isExist true;
  610.                 break;
  611.             }
  612.         }
  613.         if ($isExist) { // If alreadt exist, dont update anything
  614.             return null;
  615.         }
  616.         $person = new ContactPerson;
  617.         $person
  618.             ->setFirstName($orderBillingDetails->getFirstName())
  619.             ->setLastName($orderBillingDetails->getLastName())
  620.             ->setEmailAddress($orderBillingDetails->getEmailAddress())
  621.             ->setIncludeInEmails(false)
  622.         ;
  623.         array_push($additionalPersonsArr$person);
  624.         $contact = new Contact;
  625.         $contact
  626.             ->setContactPersons($additionalPersonsArr)
  627.         ;
  628.         $arr_contacts = [];
  629.         array_push($arr_contacts$contact);
  630.         $contacts = new Contacts;
  631.         $contacts->setContacts($arr_contacts);
  632.         // Update the organisation contact
  633.         try {
  634.             $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  635.         } catch(ApiException $e) {
  636.            $this->throwXeroException($e);
  637.         }
  638.             
  639.         if ($apiResponse[0]['has_validation_errors']) {
  640.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  641.         }
  642.         
  643.         return $apiResponse[0]['contact_id'];
  644.     }
  645.     /**
  646.      * DELETE CONTACT
  647.      *
  648.      * @param User $user
  649.      * @return void
  650.      */
  651.     public function deleteContact(User $user)
  652.     {
  653.         $userInformation $user->getUserInformation();
  654.         $xeroContactId $userInformation->getXeroId();
  655.         $contact = new Contact();
  656.         $contact
  657.             ->setContactID($xeroContactId)
  658.             ->setContactStatus('ARCHIVED')
  659.         ;
  660.         $arr_contacts = [];
  661.         array_push($arr_contacts$contact);
  662.         $contacts = new Contacts;
  663.         $contacts->setContacts($arr_contacts);
  664.         try {
  665.             $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  666.         } catch(ApiException $e) {
  667.             $this->throwXeroException($e);
  668.         } catch(Exception $e) {
  669.             return;
  670.         } 
  671.         if ($apiResponse[0]['has_validation_errors']) {
  672.             // return;
  673.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  674.         }
  675.         
  676.         return $apiResponse[0]['contact_id'];
  677.     }
  678.     private function throwXeroException(ApiException $e) {
  679.         $error AccountingObjectSerializer::deserialize(
  680.             $e->getResponseBody(),
  681.             '\XeroAPI\XeroPHP\Models\Accounting\Error',
  682.             []
  683.         );
  684.         $message "ApiException - " $error->getElements()[0]["validation_errors"][0]["message"];
  685.         $this->throwExceptionMessage($message);
  686.     }
  687. }