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