src/Service/Xero/ContactService.php line 24

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\Models\Accounting\Contact;
  12. use XeroAPI\XeroPHP\Models\Accounting\ContactPerson;
  13. use XeroAPI\XeroPHP\Models\Accounting\Contacts;
  14. use XeroAPI\XeroPHP\ApiException;
  15. use XeroAPI\XeroPHP\Models\Accounting\Address;
  16. final class ContactService extends XeroService
  17. {
  18.     private $userRepository;
  19.     public function __construct(XeroAuthenticator $xeroAuthenticatorUserRepository $userRepository)
  20.     {        
  21.         parent::__construct($xeroAuthenticator);
  22.         $this->userRepository $userRepository;
  23.     }
  24.     /**
  25.      * Create Xero contact 
  26.      *
  27.      * @param User $user
  28.      * @return string
  29.      */
  30.     public function createContact(User $user): string 
  31.     {
  32.          // Check if contact is already registered in the system
  33.         $xeroID $this->getContactByUser($user);
  34.         if (!empty($xeroID)) {
  35.             return $xeroID;
  36.         }
  37.         $contact = new Contact;
  38.         $contact->setName($user->getFirstName() . ' ' $user->getLastName())
  39.             ->setFirstName($user->getFirstName())
  40.             ->setLastName($user->getLastName())
  41.             ->setEmailAddress($user->getEmail())
  42.         ;
  43.         if ($user->getUserAddress()) {
  44.             $userAddress $user->getUserAddress();
  45.             
  46.             $address = new Address();
  47.             $address->setAddressType(Address::ADDRESS_TYPE_STREET);
  48.             if ($userAddress->getStreet()) $address->setAddressLine1($userAddress->getStreet());
  49.             if ($userAddress->getCity()) $address->setCity($userAddress->getCity());
  50.             if ($userAddress->getState()) $address->setRegion($userAddress->getState());
  51.             if ($userAddress->getPostcode()) $address->setPostalCode($userAddress->getPostcode());
  52.             if ($userAddress->getCountry()) $address->setCountry($userAddress->getCountry());
  53.             $arr_addresses = [];
  54.             array_push($arr_addresses$address);
  55.             $contact->setAddresses($arr_addresses);
  56.         }
  57.         $arr_contacts = [];
  58.         array_push($arr_contacts$contact);
  59.         $contacts = new Contacts;
  60.         $contacts->setContacts($arr_contacts);
  61.         $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  62.         if ($apiResponse[0]['has_validation_errors']) {
  63.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  64.         }
  65.         return $apiResponse[0]['contact_id'];
  66.     }
  67.     /**
  68.      * Create Xero contact 
  69.      *
  70.      * @param User $user
  71.      * @return string
  72.      */
  73.     public function createContactByProjectName(FilmProject $filmProject): string 
  74.     {
  75.         $contact = new Contact;
  76.         $user $filmProject->getOwner();
  77.         $contact->setName($filmProject->getTitle()) // Unique name here
  78.             ->setFirstName($user->getFirstName())
  79.             ->setLastName($user->getLastName())
  80.             ->setEmailAddress($user->getEmail())
  81.         ;
  82.         if ($user->getUserAddress()) {
  83.             $userAddress $user->getUserAddress();
  84.             
  85.             $address = new Address();
  86.             $address->setAddressType(Address::ADDRESS_TYPE_STREET);
  87.             if ($userAddress->getStreet()) $address->setAddressLine1($userAddress->getStreet());
  88.             if ($userAddress->getCity()) $address->setCity($userAddress->getCity());
  89.             if ($userAddress->getState()) $address->setRegion($userAddress->getState());
  90.             if ($userAddress->getPostcode()) $address->setPostalCode($userAddress->getPostcode());
  91.             if ($userAddress->getCountry()) $address->setCountry($userAddress->getCountry());
  92.             $arr_addresses = [];
  93.             array_push($arr_addresses$address);
  94.             $contact->setAddresses($arr_addresses);
  95.         }
  96.         $arr_contacts = [];
  97.         array_push($arr_contacts$contact);
  98.         $contacts = new Contacts;
  99.         $contacts->setContacts($arr_contacts);
  100.         $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  101.         if ($apiResponse[0]['has_validation_errors']) {
  102.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  103.         }
  104.         return $apiResponse[0]['contact_id'];
  105.     }
  106.     /**
  107.      * Update contact
  108.      *
  109.      * @param User $user
  110.      * @return void
  111.      */
  112.     public function updateContact(User $user)
  113.     {
  114.         $userInformation $user->getUserInformation();
  115.         $userAddress $user->getUserAddress();
  116.         $xeroContactId $userInformation->getXeroId();
  117.         $arr_addresses = [];
  118.         $address = (new Address())
  119.             ->setAddressType(Address::ADDRESS_TYPE_STREET)
  120.             ->setAddressLine1($userAddress->getStreet())
  121.             ->setCity($userAddress->getCity())
  122.             ->setPostalCode($userAddress->getPostcode())
  123.         ;
  124.         array_push($arr_addresses$address);
  125.         $contact = new Contact();
  126.         $contact
  127.             ->setName($user->getFirstName() . ' ' $user->getLastName())
  128.             ->setFirstName($user->getFirstName())
  129.             ->setLastName($user->getLastName())
  130.             ->setContactID($xeroContactId)
  131.             ->setAddresses($arr_addresses)
  132.         ;
  133.         $arr_contacts = [];
  134.         array_push($arr_contacts$contact);
  135.         $contacts = new Contacts;
  136.         $contacts->setContacts($arr_contacts);
  137.         $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  138.         if ($apiResponse[0]['has_validation_errors']) {
  139.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  140.         }
  141.         
  142.         return $apiResponse[0]['contact_id'];
  143.     }
  144.     /**
  145.      * Get contacts by email
  146.      *
  147.      * @param [type] $fullname
  148.      * @return string
  149.      */
  150.     public function getContactByUser(User $user): ?string
  151.     {
  152.         $fullName $user->getFirstName() . ' ' $user->getLastName();
  153.         /** This represents paramater needed for Xero getContacts */
  154.         $modifiedSince = new \DateTime('2010-01-01');
  155.         $where 'ContactStatus=="' Contact::CONTACT_STATUS_ACTIVE '"';
  156.         $order "Name ASC";
  157.         $page 1;
  158.         $searchTerm $user->getEmail();
  159.         $includeArchived true;
  160.         $summaryOnly true;
  161.         $contacts $this->xeroAccountingManager->getContacts($this->xeroTenantId$modifiedSince$where$ordernull$page$includeArchived$summaryOnly$searchTerm);
  162.         foreach ($contacts as $contact) {
  163.             if (strtolower($contact['name']) == strtolower($fullName)) {
  164.                 return $contact['contact_id'];
  165.             }
  166.         }
  167.         return null;
  168.     }
  169.     /**
  170.      * Get contacts by email
  171.      *
  172.      * @param [type] $fullname
  173.      * @return string
  174.      */
  175.     public function getContactByEmail(string $email): ?string
  176.     {
  177.         /** This represents paramater needed for Xero getContacts */
  178.         $modifiedSince = new \DateTime('2010-01-01');
  179.         $where 'ContactStatus=="' Contact::CONTACT_STATUS_ACTIVE '"';
  180.         $order "Name ASC";
  181.         $page 1;
  182.         $searchTerm $email;
  183.         $includeArchived true;
  184.         $summaryOnly true;
  185.         $contacts $this->xeroAccountingManager->getContacts($this->xeroTenantId$modifiedSince$where$ordernull$page$includeArchived$summaryOnly$searchTerm);
  186.         foreach ($contacts as $contact) {
  187.             if ($contact['email_address'] == $email) {
  188.                 return $contact['contact_id'];
  189.             }
  190.         }
  191.         return null;
  192.     }
  193.     /**
  194.      * Get contacts by id
  195.      *
  196.      * @param [type] $fullname
  197.      * @return obj
  198.      */
  199.     public function getContactById(string $contactId)
  200.     {
  201.         try {
  202.             $contacts $this->xeroAccountingManager->getContact($this->xeroTenantId$contactId);
  203.         }
  204.         catch (Exception $e) {
  205.             $this->throwExceptionMessage($e->getMessage());
  206.         }
  207.         
  208.         if ($contacts) {
  209.             return $contacts[0];
  210.         }
  211.         return null;
  212.     }
  213.     /**
  214.      * Get contacts by name
  215.      *
  216.      * @param [type] $fullname
  217.      * @return string
  218.      */
  219.     public function getContactByOrderDetails(OrderDetails $orderDetails): ?string
  220.     {
  221.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  222.         $user $this->userRepository->findOneBy(['email' => $orderBillingDetails->getEmailAddress()]);
  223.         $fullName $orderBillingDetails->getFirstName() .' '$orderBillingDetails->getLastName();
  224.         // TODO: ENABLED when client agree to use the same ID for the same contact integrated with the system
  225.         // if ($user) {
  226.             // $fullName = $user->getFirstName() .' '. $user->getLastName() . ' - ' . $user->getId();
  227.         //     $userInformation = $user->getUserInformation();
  228.         //     return $userInformation->getXeroId();
  229.         // }             
  230.         /** This represents paramater needed for Xero getContacts */
  231.         $modifiedSince = new \DateTime('2020-01-01');
  232.         $where 'ContactStatus=="' Contact::CONTACT_STATUS_ACTIVE '"';
  233.         $order "Name ASC";
  234.         $page 1;
  235.         // $searchTerm = $fullName;
  236.         $searchTerm =  $orderBillingDetails->getEmailAddress();
  237.         $includeArchived true;
  238.         $summaryOnly true;
  239.         $contacts $this->xeroAccountingManager->getContacts($this->xeroTenantId$modifiedSince$where$ordernull$page$includeArchived$summaryOnly$searchTerm);
  240.         foreach ($contacts as $contact) {
  241.             // if (strtolower($contact['name']) == strtolower($fullName)) {
  242.             if (str_contains(strtolower($contact['name']),strtolower($fullName) )) {
  243.                 return $contact['contact_id'];
  244.             }
  245.         }
  246.         return null;
  247.     }
  248.     
  249.     /**
  250.      * Create Xero contact 
  251.      *
  252.      * @param User $user
  253.      * @return string
  254.      */
  255.     public function createContactByOrderDetails(OrderDetails $orderDetails): string 
  256.     {
  257.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  258.         $contact = new Contact;
  259.         $contact->setName($orderBillingDetails->getFirstName() . ' ' $orderBillingDetails->getLastName() . ' - '$orderDetails->getId())
  260.                 ->setFirstName($orderBillingDetails->getFirstName())
  261.                 ->setLastName($orderBillingDetails->getLastName())
  262.                 ->setEmailAddress($orderBillingDetails->getEmailAddress());
  263.         $address = new Address();
  264.         $address->setAddressType(Address::ADDRESS_TYPE_POBOX);
  265.         if ($orderBillingDetails->getStreet()) $address->setAddressLine1($orderBillingDetails->getStreet());
  266.         if ($orderBillingDetails->getSuburb()) $address->setCity($orderBillingDetails->getSuburb());
  267.         if ($orderBillingDetails->getState()) $address->setRegion($orderBillingDetails->getState());
  268.         if ($orderBillingDetails->getPostcode()) $address->setPostalCode($orderBillingDetails->getPostcode());
  269.         if ($orderBillingDetails->getCountry()) $address->setCountry($orderBillingDetails->getCountry());
  270.         $arr_addresses = [];
  271.         array_push($arr_addresses$address);
  272.         $contact->setAddresses($arr_addresses);
  273.         $arr_contacts = [];
  274.         array_push($arr_contacts$contact);
  275.         $contacts = new Contacts;
  276.         $contacts->setContacts($arr_contacts);
  277.         $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  278.         if ($apiResponse[0]['has_validation_errors']) {
  279.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  280.         }
  281.         return $apiResponse[0]['contact_id'];
  282.     }
  283.     /**
  284.      * Create Xero contact 
  285.      *
  286.      * @param User $user
  287.      * @return string
  288.      */
  289.     public function createGuestContactByOrderDetails(OrderDetails $orderDetails): string 
  290.     {
  291.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  292.         $contact = new Contact;
  293.         $contact->setName($orderBillingDetails->getFirstName() . ' ' $orderBillingDetails->getLastName())
  294.                 ->setFirstName($orderBillingDetails->getFirstName())
  295.                 ->setLastName($orderBillingDetails->getLastName())
  296.                 ->setEmailAddress($orderBillingDetails->getEmailAddress());
  297.         $arr_contacts = [];
  298.         array_push($arr_contacts$contact);
  299.         $contacts = new Contacts;
  300.         $contacts->setContacts($arr_contacts);
  301.         $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  302.         if ($apiResponse[0]['has_validation_errors']) {
  303.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  304.         }
  305.         return $apiResponse[0]['contact_id'];
  306.     }
  307.     
  308.     /**
  309.      * Update Xero contact details
  310.      *
  311.      * @param OrderDetails $orderDetails
  312.      * @param [type] $xeroContactId
  313.      * @return void
  314.      */
  315.     public function updateContactByOrderDetails(OrderDetails $orderDetails$xeroContactId)
  316.     {
  317.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  318.         $contact = new Contact();
  319.         $contact
  320.             // ->setName($orderBillingDetails->getFirstName() . ' ' . $orderBillingDetails->getLastName())
  321.             ->setFirstName($orderBillingDetails->getFirstName())
  322.             ->setLastName($orderBillingDetails->getLastName())
  323.             ->setEmailAddress($orderBillingDetails->getEmailAddress())
  324.             ->setContactID($xeroContactId)
  325.             // TODO: set other fields such as address
  326.         ;
  327.         $address = new Address();
  328.         $address->setAddressType(Address::ADDRESS_TYPE_POBOX);
  329.         if ($orderBillingDetails->getStreet()) $address->setAddressLine1($orderBillingDetails->getStreet());
  330.         if ($orderBillingDetails->getSuburb()) $address->setCity($orderBillingDetails->getSuburb());
  331.         if ($orderBillingDetails->getState()) $address->setRegion($orderBillingDetails->getState());
  332.         if ($orderBillingDetails->getPostcode()) $address->setPostalCode($orderBillingDetails->getPostcode());
  333.         if ($orderBillingDetails->getCountry()) $address->setCountry($orderBillingDetails->getCountry());
  334.         $arr_addresses = [];
  335.         array_push($arr_addresses$address);
  336.         $contact->setAddresses($arr_addresses);
  337.         $arr_contacts = [];
  338.         array_push($arr_contacts$contact);
  339.         $contacts = new Contacts;
  340.         $contacts->setContacts($arr_contacts);
  341.         $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  342.         if ($apiResponse[0]['has_validation_errors']) {
  343.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  344.         }
  345.         
  346.         return $apiResponse[0]['contact_id'];
  347.     }
  348.     
  349.     /**
  350.      * Check if contact exists on current XERO contact Id
  351.      *
  352.      * @param [type] $contactId
  353.      * @return void
  354.      */
  355.     public function checkContactExists($xeroContactId) {
  356.         $isExist false;
  357.         try {
  358.             $apiResponse $this->xeroAccountingManager->getContact($this->xeroTenantId$xeroContactId);
  359.         } catch (ApiException $e) {
  360.             return $isExist;
  361.         }
  362.         if (!$apiResponse[0]['HasValidationErrors']) {
  363.             $isExist true;
  364.         }
  365.     
  366.         return $isExist;
  367.     }
  368.     
  369.     /**
  370.      * Update contact
  371.      *
  372.      * @param OrderDetails $orderDetails
  373.      * @param string $xeroContactId
  374.      * @return void
  375.      */
  376.     public function updateContactById(OrderDetails $orderDetailsstring $xeroContactId)
  377.     {
  378.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  379.         $contact = new Contact();
  380.         $contact
  381.             ->setFirstName($orderBillingDetails->getFirstName())
  382.             ->setLastName($orderBillingDetails->getLastName())
  383.         ;
  384.         $arr_contacts = [];
  385.         array_push($arr_contacts$contact);
  386.         $contacts = new Contacts;
  387.         $contacts->setContacts($arr_contacts);
  388.         $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  389.         if ($apiResponse[0]['has_validation_errors']) {
  390.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  391.         }
  392.         
  393.         return $apiResponse[0]['contact_id'];
  394.     }
  395.     /**
  396.      * Get contacts by organisation name
  397.      *
  398.      * @param OrderDetails $orderDetails
  399.      * @return string
  400.      */
  401.     public function getContactOrganisationByOrderDetails(OrderDetails $orderDetails): ?string
  402.     {
  403.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  404.         $fullName $orderBillingDetails->getOrganisation();
  405.         /** This represents paramater needed for Xero getContacts */
  406.         $modifiedSince = new \DateTime('2020-01-01');
  407.         $where 'ContactStatus=="' Contact::CONTACT_STATUS_ACTIVE '"';
  408.         $order "Name ASC";
  409.         $page 1;
  410.         $searchTerm $fullName;
  411.         // $searchTerm =  $orderBillingDetails->getEmailAddress();
  412.         $includeArchived true;
  413.         $summaryOnly true;
  414.         $contacts $this->xeroAccountingManager->getContacts($this->xeroTenantId$modifiedSince$where$ordernull$page$includeArchived$summaryOnly$searchTerm);
  415.         foreach ($contacts as $contact) { // Make sure that the actual name is exactly the same as the search results
  416.             if (strtolower($contact['name']) == strtolower($fullName)) {
  417.                 return $contact['contact_id'];
  418.             }
  419.         }
  420.         return null;
  421.     }
  422.     /**
  423.      * Create Xero contact with organisation name 
  424.      *
  425.      * @param User $user
  426.      * @return string
  427.      */
  428.     public function createContactOrganisationByOrderDetails(OrderDetails $orderDetails): string 
  429.     {
  430.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  431.         $contact = new Contact;
  432.         $contact->setName($orderBillingDetails->getOrganisation())
  433.                 ->setFirstName($orderBillingDetails->getFirstName())
  434.                 ->setLastName($orderBillingDetails->getLastName())
  435.                 ->setEmailAddress($orderBillingDetails->getEmailAddress());
  436.         $arr_contacts = [];
  437.         array_push($arr_contacts$contact);
  438.         $contacts = new Contacts;
  439.         $contacts->setContacts($arr_contacts);
  440.         $apiResponse $this->xeroAccountingManager->createContacts($this->xeroTenantId$contacts);
  441.         if ($apiResponse[0]['has_validation_errors']) {
  442.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  443.         }
  444.         return $apiResponse[0]['contact_id'];
  445.     }
  446.     /**
  447.      * Gets all the additional persons from the contact based on XERO ID
  448.      *
  449.      * @param string $xeroID
  450.      * @return void|arr
  451.      */
  452.     private function getOrganisationAdditionalPersonByXeroId(string $xeroID)
  453.     {
  454.         $result = [];
  455.         $contact $this->getContactById($xeroID);
  456.         if (!empty($contact['contact_persons'])) {
  457.             return $contact['contact_persons'];
  458.         }
  459.         return $result;
  460.     }
  461.     /**
  462.      * Adds a new person as an additional person in the contact
  463.      *
  464.      * @param OrderDetails $orderDetails
  465.      * @param [type] $xeroContactId
  466.      * @return void
  467.      */
  468.     public function updateOrganisationWithAdditionalPersonByOrderDetails(OrderDetails $orderDetails$xeroContactId)
  469.     {
  470.         $orderBillingDetails $orderDetails->getOrderBillingDetails();
  471.         // Check if the order billing details already exists as one of the additional person arr
  472.         $additionalPersonsArr $this->getOrganisationAdditionalPersonByXeroId($xeroContactId);
  473.         $isExist false;
  474.         foreach ($additionalPersonsArr as $personArr) {
  475.             if ($orderBillingDetails->getFirstName() == $personArr->getFirstName() && $orderBillingDetails->getLastName() == $personArr->getLastName() && $orderBillingDetails->getEmailAddress() == $personArr->getEmailAddress()) {
  476.                 $isExist true;
  477.                 break;
  478.             }
  479.         }
  480.         if ($isExist) { // If alreadt exist, dont update anything
  481.             return null;
  482.         }
  483.         $person = new ContactPerson;
  484.         $person
  485.             ->setFirstName($orderBillingDetails->getFirstName())
  486.             ->setLastName($orderBillingDetails->getLastName())
  487.             ->setEmailAddress($orderBillingDetails->getEmailAddress())
  488.             ->setIncludeInEmails(false)
  489.         ;
  490.         array_push($additionalPersonsArr$person);
  491.         $contact = new Contact;
  492.         $contact
  493.             ->setContactPersons($additionalPersonsArr)
  494.         ;
  495.         $arr_contacts = [];
  496.         array_push($arr_contacts$contact);
  497.         $contacts = new Contacts;
  498.         $contacts->setContacts($arr_contacts);
  499.         // Update the organisation contact
  500.         $apiResponse $this->xeroAccountingManager->updateContact($this->xeroTenantId$xeroContactId$contacts);
  501.         if ($apiResponse[0]['has_validation_errors']) {
  502.             $this->throwExceptionMessage($apiResponse[0]['validation_errors'][0]['message']);
  503.         }
  504.         
  505.         return $apiResponse[0]['contact_id'];
  506.     }
  507. }