Working with Shopware B2B

Getting into Shopware B2B customers, contacts, debtors.

So let's dig a bit on how Shopware B2B works contacts works.

The task: we created some custom fields which have some data for the debtors customer accounts, we wanted to make that data available for the contacts customers accounts.

For that matter we were thinking on create a resolver that will have a method to get the custom fields information by passing through the current customer ID.

The issue: there's none relation in tables to know if the current customer is a contact.

How we got the relation working? Not easy...

This is a hell of custom queries, though it's all explained in the first method "getContactDebtor", the flow goes like this:

- Get the current customer data (this is kind of an additional step because we wanted to use the customer ID)

- This will give us the current customer E-mail which will use to run a query on the "b2b_debtor_contact" table.

- That table will give us the current customer "auth_id" which will use to get the "context_owner_id".

- That "context_owner_id" is the "auth_id" of the debtor, so run a second query on the same table to get the debtor entry.

- In this second entry the "provider_context" is the customer ID of the debtor which will allow us to get the debtor customer data and with it the customer custom fields.

Here you can check the working code:

 /**
 * @param $customerId
 *
 * @return mixed|null
 */
 private function getContactDebtor($customerId)
 {
 // first we need the get the customer data:
 /** @var CustomerEntity $contactCustomer */
 $contactCustomer = $this->getCustomer($customerId);
 // this will give us the $customerEmail, which we can use to get the contact auth_id:
 $contactData = $this->getContactFromEmail($contactCustomer->getEmail());
 if (!$contactData) {
 return false;
 }
 // after we get the contact entity we need to get the contact auth record:
 $contactAuthData = $this->getAuthRecord($contactData['auth_id']);
 // the auth record will give us the "context_owner_id", which is the debtor auth_id:
 $debtorAuthData = $this->getAuthRecord($contactAuthData['context_owner_id']);

 // now we can use the "provider_context" which (in the case of the debtor) is the related customer Id:
 return $this->getCustomer($debtorAuthData['provider_context']);
 }

 /**
 * @param $email
 */
 private function getContactFromEmail($email)
 {
 $contactQuery = $this->connection->createQueryBuilder()
 ->select('auth_id')
 ->from(self::CONTACT_TABLE, self::CONTACT_ALIAS)
 ->where(self::CONTACT_ALIAS . '.email = :email')
 ->setParameter('email', $email);

 return $contactQuery->execute()->fetch(\PDO::FETCH_ASSOC);
 }

 /**
 * @param $authId
 */
 private function getAuthRecord($authId): array
 {
 $authQuery = $this->connection->createQueryBuilder()
 ->select('*')
 ->from(self::B2B_AUTH_TABLE, self::B2B_AUTH_ALIAS)
 ->where(self::B2B_AUTH_ALIAS . '.id = :authId')
 ->setParameter('authId', $authId);

 return $authQuery->execute()->fetch(\PDO::FETCH_ASSOC);
 }

 /**
 * @param $customerId
 *
 * @return mixed|null
 */
 private function getCustomer($customerId)
 {
 return $this->customerRepository->search(
 (new Criteria())
 ->addFilter(new EqualsFilter('customer.id', $customerId))
 ->setLimit(1),
 $this->contextProvider->getContext()
 )->get($customerId);
 }

Hope this helps someone!

Comments

* - Required fields