/** * There can be only one primary entity * * @param Contact $entity */ public function updatePrimaryEntities(Contact $entity) { // update addresses $addresses = $entity->getAddresses(); $primaryAddress = $this->getPrimaryEntity($addresses); if ($primaryAddress) { $entity->setPrimaryAddress($primaryAddress); } elseif ($addresses->count() > 0) { $entity->setPrimaryAddress($addresses->first()); } // update emails $emails = $entity->getEmails(); $primaryEmail = $this->getPrimaryEntity($emails); if ($primaryEmail) { $entity->setPrimaryEmail($primaryEmail); } elseif ($emails->count() > 0) { $entity->setPrimaryEmail($emails->first()); } // update phones $phones = $entity->getPhones(); $primaryPhone = $this->getPrimaryEntity($phones); if ($primaryPhone) { $entity->setPrimaryPhone($primaryPhone); } elseif ($phones->count() > 0) { $entity->setPrimaryPhone($phones->first()); } }
/** * @param Contact $contact * @param ContactAddress $address * @return array * @throws BadRequestHttpException */ protected function update(Contact $contact, ContactAddress $address) { $responseData = array('saved' => false, 'contact' => $contact); if ($this->getRequest()->getMethod() == 'GET' && !$address->getId()) { $address->setFirstName($contact->getFirstName()); $address->setLastName($contact->getLastName()); if (!$contact->getAddresses()->count()) { $address->setPrimary(true); } } if ($address->getOwner() && $address->getOwner()->getId() != $contact->getId()) { throw new BadRequestHttpException('Address must belong to contact'); } elseif (!$address->getOwner()) { $contact->addAddress($address); } // Update contact's modification date when an address is changed $contact->setUpdatedAt(new \DateTime('now', new \DateTimeZone('UTC'))); if ($this->get('orocrm_contact.form.handler.contact_address')->process($address)) { $this->getDoctrine()->getManager()->flush(); $responseData['entity'] = $address; $responseData['saved'] = true; } $responseData['form'] = $this->get('orocrm_contact.contact_address.form')->createView(); return $responseData; }
/** * Do merge of non-scalar fields such as emails or addresses * * @param Customer $remoteData * @param Customer $localData * @param Contact $contact * * @SuppressWarnings(PHPMD) * TODO Should be fixed during CRM-1185 */ public function mergeObjects(Customer $remoteData, Customer $localData, Contact $contact) { // process emails $email = $contact->getPrimaryEmail(); if ($email) { // if primary email exists try to merge $this->mergeScalars(['email'], $remoteData, $localData, $email); } elseif ($this->isRemotePrioritized()) { // if contact hasn't email and remote data has greater priority, then create it $email = new ContactEmail(); $email->setPrimary(true); $email->setEmail($remoteData->getEmail()); $contact->addEmail($email); } // process addresses $addresses = $contact->getAddresses(); $isLocalTypesChanged = $this->isLocalAddressesTypesChanged($addresses, $localData); foreach ($addresses as $address) { // find in update local data if $localAddress = $this->getCustomerAddressByContactAddress($localData, $address); if (!$localAddress && $this->isRemotePrioritized()) { $contact->removeAddress($address); } elseif ($localAddress) { $remoteAddress = $this->getCorrespondentRemoteAddress($remoteData, $localAddress); if ($remoteAddress) { // do update $this->mergeScalars($this->addressScalarFields, $remoteAddress, $localAddress, $address); if ($localAddress->getCountry()->getIso2Code() === $address->getCountry()->getIso2Code() || $this->isRemotePrioritized()) { $address->setCountry($remoteAddress->getCountry()); } if ($this->isRegionChanged($remoteAddress, $address) || $this->isRemotePrioritized()) { $address->setRegion($remoteAddress->getRegion()); if ($address->getRegion()) { $address->setRegionText(null); } } if ($this->isRemotePrioritized() || !$isLocalTypesChanged) { $address->setTypes($remoteAddress->getTypes()); } $contactPhone = null; if ($localAddress->getContactPhone()) { $contactPhone = $this->getContactPhoneFromContact($contact, $localAddress->getContactPhone()); } if ($contactPhone) { $this->mergeScalars(['phone'], $remoteAddress, $localAddress, $contactPhone); } elseif ($this->isRemotePrioritized() && $remoteAddress->getPhone() !== 'no phone') { $contactPhone = new ContactPhone(); $contactPhone->setPhone($remoteAddress->getPhone()); $contactPhone->setPrimary(!$contact->getPrimaryPhone()); $contact->addPhone($contactPhone); $localAddress->setContactPhone($contactPhone); } $this->prepareAddress($address); if (!$address->getCountry()) { $contact->removeAddress($address); } } else { $contact->removeAddress($address); } } } /** @var ArrayCollection|Address[] $newAddresses */ $newAddresses = $this->getOrphanRemoteAddresses($remoteData, $localData); foreach ($newAddresses as $address) { /* * Will create new address if remote data has higher priority and means * that address removed from contact and remove should be cancelled. * Another case if it's newly created address, then process it anyway */ if ($this->isRemotePrioritized() || !$address->getId()) { $contactAddress = new ContactAddress(); $this->mergeScalars($this->addressScalarFields, $address, $contactAddress, $contactAddress); $contactAddress->setCountry($address->getCountry()); $contactAddress->setRegion($address->getRegion()); $contactAddress->setTypes($address->getTypes()); $this->prepareAddress($contactAddress); if ($contactAddress->getCountry()) { $contact->addAddress($contactAddress); $address->setContactAddress($contactAddress); } if ($address->getContactPhone()) { $address->getContactPhone()->setOwner($contact); } } } /** @var ContactAddress $toBePrimary */ $toBePrimary = $contact->getAddresses()->first(); if (!$contact->getPrimaryAddress() && $toBePrimary) { $toBePrimary->setPrimary(true); } // Set contact primary phone if none if (!$contact->getPrimaryPhone()) { if ($contact->getPhones()->count() > 0) { $contact->getPhones()->first()->setPrimary(true); } } }
/** * @param Contact $entity * @param array $result * * @return array */ protected function prepareContactEntities(Contact $entity, array $result) { // use contact source name instead of label $source = $entity->getSource(); if ($source) { $result['source'] = $source->getName(); } else { $result['source'] = null; } // use contact method name instead of label $method = $entity->getMethod(); if ($method) { $result['method'] = $method->getName(); } else { $result['method'] = null; } $result['emails'] = array(); foreach ($entity->getEmails() as $email) { $result['emails'][] = array('email' => $email->getEmail(), 'primary' => $email->isPrimary()); } $result['phones'] = array(); foreach ($entity->getPhones() as $phone) { $result['phones'][] = array('phone' => $phone->getPhone(), 'primary' => $phone->isPrimary()); } // set contact group data $groupsData = array(); foreach ($entity->getGroups() as $group) { $groupsData[] = parent::getPreparedItem($group); } $result['groups'] = $groupsData; // convert addresses to plain array $addressData = array(); /** @var $address ContactAddress */ foreach ($entity->getAddresses() as $address) { $addressArray = parent::getPreparedItem($address); $addressArray['types'] = $address->getTypeNames(); $addressArray = $this->removeUnusedValues($addressArray, array('owner')); // @todo: just a temporary workaround until new API is implemented // the normal solution can be to use region_name virtual field and // exclusion rule declared in oro/entity.yml // - for 'region' field use a region text if filled; otherwise, use region name // - remove regionText field from a result if (!empty($addressArray['regionText'])) { $addressArray['region'] = $addressArray['regionText']; } unset($addressArray['regionText']); $addressData[] = $addressArray; } $result['addresses'] = $addressData; return $result; }
/** * Update $entity with new contact data * * @param Customer $remoteData * @param Customer $localData * @param Contact $contact */ protected function updateContact(Customer $remoteData, Customer $localData, Contact $contact) { $helper = new ContactImportHelper($localData->getChannel(), $this->addressHelper); if ($localData->getContact() && $localData->getContact()->getId()) { $helper->merge($remoteData, $localData, $localData->getContact()); } else { $addresses = $localData->getAddresses(); // loop by imported addresses, add new only /** @var \OroCRM\Bundle\ContactBundle\Entity\ContactAddress $address */ foreach ($contact->getAddresses() as $key => $address) { $helper->prepareAddress($address); if (!$address->getCountry()) { $contact->removeAddress($address); continue; } // @TODO find possible solution // guess parent address by key if ($entity = $addresses->get($key)) { $entity->setContactAddress($address); } } // @TODO find possible solution // guess parent $phone by key foreach ($contact->getPhones() as $key => $phone) { $contactPhone = $this->getContactPhoneFromContact($contact, $phone); if ($entity = $addresses->get($key)) { $entity->setContactPhone($contactPhone ? $contactPhone : $phone); } } // populate default owner only for new contacts $this->defaultOwnerHelper->populateChannelOwner($contact, $localData->getChannel()); $localData->setContact($contact); } }
/** * @param Contact $entity * @return Contact */ protected function afterProcessEntity($entity) { // there can be only one primary entity $addresses = $entity->getAddresses(); $primaryAddress = $this->getPrimaryEntity($addresses); if ($primaryAddress) { /** @var ContactAddress $primaryAddress */ $entity->setPrimaryAddress($primaryAddress); } elseif ($addresses->count() > 0) { $entity->setPrimaryAddress($addresses->first()); } $emails = $entity->getEmails(); $primaryEmail = $this->getPrimaryEntity($emails); if ($primaryEmail) { /** @var ContactEmail $primaryEmail */ $entity->setPrimaryEmail($primaryEmail); } elseif ($emails->count() > 0) { $entity->setPrimaryEmail($emails->first()); } $phones = $entity->getPhones(); $primaryPhone = $this->getPrimaryEntity($phones); if ($primaryPhone) { /** @var ContactPhone $primaryPhone */ $entity->setPrimaryPhone($primaryPhone); } elseif ($phones->count() > 0) { $entity->setPrimaryPhone($phones->first()); } return $entity; }
/** * @param Contact $entity */ protected function processMultipleRelations(Contact $entity) { // update groups foreach ($entity->getGroups() as $group) { $entity->removeGroup($group); if ($group = $this->findExistingEntity($group)) { $entity->addGroup($group); } } // clear accounts foreach ($entity->getAccounts() as $account) { $entity->removeAccount($account); } // update addresses /** @var ContactAddress $contactAddress */ foreach ($entity->getAddresses() as $contactAddress) { // update address types foreach ($contactAddress->getTypes() as $addressType) { $contactAddress->removeType($addressType); $existingAddressType = $this->findExistingEntity($addressType); if ($existingAddressType) { $contactAddress->addType($existingAddressType); } } } }