Display Associated Custom Objects of Related Companies

SOLVE
cives
Participant

I'm currently developing a user portal with CMS Membership. When a contact in our Hubspot database creates an account, they have the ability to go to a screen to see a list of Safety Documents (these are custom objects) that are associated with the company that the contact is associated with.

 

There are some instances where a user who works for 'Company A' would also need to see custom objects for Company A's child companies Company B, C, D, etc.

 

I see that there is a way to create that relationship in HubSpot on the companies tab using related companies. What I'm unsure of is if Contact of Company A is logged in, is there a way to code it so that they can see affiliated custom objects for child companies?

 

I'm currently using this code to pull only parent company associations:

 

 

<div class="table-responsive">
<table class="table table-nowrap table-centered mb-0">
<tbody>
{% set companyID = contact.associatedcompanyid %} 
{% set associated_objects = crm_associations(companyID, "USER_DEFINED", 2, "&orderBy=-date_completed", "document_type,document_number,date_completed,document_url", false) %} 
{% set type = crm_property_definition("p4829685_safety_documents", "document_type") %} 

{% for object in associated_objects.results %} 

<tr class="mix {% for option in type.options %} {% if option.value == object.document_type %} {{ option.label|replace(' ','-')|lower }} {% endif %} {% endfor %}">

<td>
<h5 class="text-truncate font-size-14 m-0"><a class="text-dark" href="{{ object.document_url }}" target="_blank">{% for option in type.options %} {% if option.value == object.document_type %} {{ option.label }} {% endif %} {% endfor %}</a></h5>
</td>

<td>{{ object.date_completed|datetimeformat('%m/%d/%y') }}</td>

<td>
<div class="team">
<a class="btn btn-success btn-sm btn-rounded" href="{{ object.document_url }}" target="_blank">Download</a>
</div>
</td>

</tr>
{% endfor %}

</tbody>
</table>
</div>

 

 

Which renders something like:
Screen Shot 2021-07-29 at 1.29.00 PM.png

However, I also need "safety audits" from child companies b,c,d to fall into this list.

 

My thought is 

contact > get associated companies > get associated parent companies > get association custom objects to the parent companies

I found a parent company to child company association here:
https://legacydocs.hubspot.com/docs/methods/crm-associations/crm-associations-overview
 
But I'm unsure how to edit my existing code to accomplish the above, I believe the snippet below is a good start. Any thoughts or ideas? Any help is appreciated.
{% set associated_child_objects  = crm_associations(companyID,  "HUBSPOT_DEFINED", 13, "&orderBy=-date_completed", "document_type,document_number,date_completed,document_url", false) %}
0 Upvotes
2 Accepted solutions

Accepted Solutions
miljkovicmisa
Solution
Top Contributor | Gold Partner

Hello @cives , thank you for writing in the forum!

The line you posted is actually what you need, so this line will produce all the child companies of that company, so all you need it to treat it like the safety documents object. Your `associated_child_objects ` variable will contain an object with the name `results`, just like the `associated_objects` variable.

So what you need to do is before the closing `</tbody>` tag you will get all the associated companies and loop through them, collecting all the related documents for each one and outputting them. Below you can see the modified verision of your code to include all the children companies documents.

I added extra comments in the code snippet so you can follow what's happening.

 

 

 

<div class="table-responsive">
<table class="table table-nowrap table-centered mb-0">
<tbody>
{% set companyID = contact.associatedcompanyid %} 
{% set associated_objects = crm_associations(companyID, "USER_DEFINED", 2, "&orderBy=-date_completed", "document_type,document_number,date_completed,document_url", false) %} 
{% set type = crm_property_definition("p4829685_safety_documents", "document_type") %} 

{% for object in associated_objects.results %} 

<tr class="mix {% for option in type.options %} {% if option.value == object.document_type %} {{ option.label|replace(' ','-')|lower }} {% endif %} {% endfor %}">

<td>
<h5 class="text-truncate font-size-14 m-0"><a class="text-dark" href="{{ object.document_url }}" target="_blank">{% for option in type.options %} {% if option.value == object.document_type %} {{ option.label }} {% endif %} {% endfor %}</a></h5>
</td>

<td>{{ object.date_completed|datetimeformat('%m/%d/%y') }}</td>

<td>
<div class="team">
<a class="btn btn-success btn-sm btn-rounded" href="{{ object.document_url }}" target="_blank">Download</a>
</div>
</td>

</tr>
{% endfor %}

{# Here we start looping through all the child companies #}

{# first getting associated child companies with your code #}
{% set associated_child_companies  = crm_associations(companyID,  "HUBSPOT_DEFINED", 13) %}

{# next begin the loop, just like for the documents #}
{% for childCompany in associated_child_companies.results %} 

{# now that we are inside an associated company we need to get the associated files just like you do for the parent company #}
{% set childCompanyID = childCompany.id %}
{% set associated_child_objects = crm_associations(childCompanyID, "USER_DEFINED", 2, "&orderBy=-date_completed", "document_type,document_number,date_completed,document_url", false) %} 

{# and finally we got the documents now so we loop through them like before #}
{% for childObject in associated_child_objects.results %} 

<tr class="mix {% for option in type.options %} {% if option.value == childObject.document_type %} {{ option.label|replace(' ','-')|lower }} {% endif %} {% endfor %}">

<td>
<h5 class="text-truncate font-size-14 m-0"><a class="text-dark" href="{{ childObject.document_url }}" target="_blank">{% for option in type.options %} {% if option.value == childObject.document_type %} {{ option.label }} {% endif %} {% endfor %}</a></h5>
</td>

<td>{{ childObject.date_completed|datetimeformat('%m/%d/%y') }}</td>

<td>
<div class="team">
<a class="btn btn-success btn-sm btn-rounded" href="{{ childObject.document_url }}" target="_blank">Download</a>
</div>
</td>

</tr>
{% endfor %}

{% endfor %}

</tbody>
</table>
</div>

 

 

 

 

If my answer was helpful, please mind marking it as a solution

View solution in original post

0 Upvotes
miljkovicmisa
Solution
Top Contributor | Gold Partner

Hello @cives ,

Happy I was helpful about the first part,

About your question no. 1:
You need to output the `{{ childCompany.name  }}` not `childObject`, this is from the second iteration. See my modified code below:

 

{# next begin the loop, just like for the documents #}
{% for childCompany in associated_child_companies.results %}

{# modified to output the name of each child company #}
<tr><td>{{ childCompany.name }}<td></tr>

{# now that we are inside an associated company we need to get the associated files just like you do for the parent company #}
{% set childCompanyID = childCompany.id %}
{% set associated_child_objects = crm_associations(childCompanyID, "USER_DEFINED", 2, "&orderBy=-date_completed", "document_type,document_number,date_completed,document_url", false) %} 

 



About question no. 2:
You need to clarify how would you like your table to look like, if you output the company name before each iteration then you will end up with multiple outputs of company name. For example, let's say that company A has 3 documents one in Janury, one in February and one in December, and then you have company B with two documents, one in April and one in July, thus you will end up with the table that looks like this:

 

COMPANY A
doc January
doc February
COMPANY B
doc April
doc July
COMPANY A
doc December

 

This table isn't terrible but there is no other way to organize the data so it's ordered by date, except if you add a column about the company, this will look like this:

 

doc January COMPANY A
doc February COMPANY A
doc April COMPANY B
doc July COMPANY B
doc December COMPANY A

 

If you chose to go with the second then you need to collect all the data from the loops (you will need both loops again) and store that data in a new dictionary.
Then with a single loop in that dictionary and some filtering you will generate the table in the example.

 

I know this is a bit cumbersome information but if you need help I could post the finished code here, I just think it's a nice excercise and you should try to do this by yourself, I believe you can. Post your code here with further questions if you find it hard, I'll be happy to help.
Below you will find info about storing data in the dictionary and how to apply filtering by some value:

Updating a dictionary with a loop (.update) (this actually shows the .update operation, you will need .append instead)
Adding to the dictionary (.append) (you will use this operation instead of .update from the previous link)

Filtering data (this is the final step to output the data by date)

Hope this helps, again, if you need more help don't hesitate to ask for it, just do give it a shot and try it on yourself first, then post your code here and we will help you 😉

If my answer was helpful please mark it as a solution.

View solution in original post

5 Replies 5
dennisedson
Community Manager

@piersg , @miljkovicmisa , @Indra 

any of you all have thoughts here?

Thanks,

Dennis




Check out our Community Developer Blog
where we feature our Community driven developer podcast and how to content
0 Upvotes
miljkovicmisa
Solution
Top Contributor | Gold Partner

Hello @cives , thank you for writing in the forum!

The line you posted is actually what you need, so this line will produce all the child companies of that company, so all you need it to treat it like the safety documents object. Your `associated_child_objects ` variable will contain an object with the name `results`, just like the `associated_objects` variable.

So what you need to do is before the closing `</tbody>` tag you will get all the associated companies and loop through them, collecting all the related documents for each one and outputting them. Below you can see the modified verision of your code to include all the children companies documents.

I added extra comments in the code snippet so you can follow what's happening.

 

 

 

<div class="table-responsive">
<table class="table table-nowrap table-centered mb-0">
<tbody>
{% set companyID = contact.associatedcompanyid %} 
{% set associated_objects = crm_associations(companyID, "USER_DEFINED", 2, "&orderBy=-date_completed", "document_type,document_number,date_completed,document_url", false) %} 
{% set type = crm_property_definition("p4829685_safety_documents", "document_type") %} 

{% for object in associated_objects.results %} 

<tr class="mix {% for option in type.options %} {% if option.value == object.document_type %} {{ option.label|replace(' ','-')|lower }} {% endif %} {% endfor %}">

<td>
<h5 class="text-truncate font-size-14 m-0"><a class="text-dark" href="{{ object.document_url }}" target="_blank">{% for option in type.options %} {% if option.value == object.document_type %} {{ option.label }} {% endif %} {% endfor %}</a></h5>
</td>

<td>{{ object.date_completed|datetimeformat('%m/%d/%y') }}</td>

<td>
<div class="team">
<a class="btn btn-success btn-sm btn-rounded" href="{{ object.document_url }}" target="_blank">Download</a>
</div>
</td>

</tr>
{% endfor %}

{# Here we start looping through all the child companies #}

{# first getting associated child companies with your code #}
{% set associated_child_companies  = crm_associations(companyID,  "HUBSPOT_DEFINED", 13) %}

{# next begin the loop, just like for the documents #}
{% for childCompany in associated_child_companies.results %} 

{# now that we are inside an associated company we need to get the associated files just like you do for the parent company #}
{% set childCompanyID = childCompany.id %}
{% set associated_child_objects = crm_associations(childCompanyID, "USER_DEFINED", 2, "&orderBy=-date_completed", "document_type,document_number,date_completed,document_url", false) %} 

{# and finally we got the documents now so we loop through them like before #}
{% for childObject in associated_child_objects.results %} 

<tr class="mix {% for option in type.options %} {% if option.value == childObject.document_type %} {{ option.label|replace(' ','-')|lower }} {% endif %} {% endfor %}">

<td>
<h5 class="text-truncate font-size-14 m-0"><a class="text-dark" href="{{ childObject.document_url }}" target="_blank">{% for option in type.options %} {% if option.value == childObject.document_type %} {{ option.label }} {% endif %} {% endfor %}</a></h5>
</td>

<td>{{ childObject.date_completed|datetimeformat('%m/%d/%y') }}</td>

<td>
<div class="team">
<a class="btn btn-success btn-sm btn-rounded" href="{{ childObject.document_url }}" target="_blank">Download</a>
</div>
</td>

</tr>
{% endfor %}

{% endfor %}

</tbody>
</table>
</div>

 

 

 

 

If my answer was helpful, please mind marking it as a solution

View solution in original post

0 Upvotes
cives
Participant

@miljkovicmisa thank you so much for the response. This appears to be working but I have two questions:

 

1. Would it be possible to print the name of the company or child company associated with the custom object? It appears that 

<td>{{ company_name }}</td>

will print the parent company name for all of them, however;

<td>{{ childObject.company_name }}</td>

 will not pull the child company's name.

 

2.  Is it possible to accomplish this using one for loop? I only ask because I would like the table to be able to display all rows by date. Right now it will show the parent company rows by date, and then it starts the child company loop by date.

 

I really appreciate your response/assistance!

0 Upvotes
miljkovicmisa
Solution
Top Contributor | Gold Partner

Hello @cives ,

Happy I was helpful about the first part,

About your question no. 1:
You need to output the `{{ childCompany.name  }}` not `childObject`, this is from the second iteration. See my modified code below:

 

{# next begin the loop, just like for the documents #}
{% for childCompany in associated_child_companies.results %}

{# modified to output the name of each child company #}
<tr><td>{{ childCompany.name }}<td></tr>

{# now that we are inside an associated company we need to get the associated files just like you do for the parent company #}
{% set childCompanyID = childCompany.id %}
{% set associated_child_objects = crm_associations(childCompanyID, "USER_DEFINED", 2, "&orderBy=-date_completed", "document_type,document_number,date_completed,document_url", false) %} 

 



About question no. 2:
You need to clarify how would you like your table to look like, if you output the company name before each iteration then you will end up with multiple outputs of company name. For example, let's say that company A has 3 documents one in Janury, one in February and one in December, and then you have company B with two documents, one in April and one in July, thus you will end up with the table that looks like this:

 

COMPANY A
doc January
doc February
COMPANY B
doc April
doc July
COMPANY A
doc December

 

This table isn't terrible but there is no other way to organize the data so it's ordered by date, except if you add a column about the company, this will look like this:

 

doc January COMPANY A
doc February COMPANY A
doc April COMPANY B
doc July COMPANY B
doc December COMPANY A

 

If you chose to go with the second then you need to collect all the data from the loops (you will need both loops again) and store that data in a new dictionary.
Then with a single loop in that dictionary and some filtering you will generate the table in the example.

 

I know this is a bit cumbersome information but if you need help I could post the finished code here, I just think it's a nice excercise and you should try to do this by yourself, I believe you can. Post your code here with further questions if you find it hard, I'll be happy to help.
Below you will find info about storing data in the dictionary and how to apply filtering by some value:

Updating a dictionary with a loop (.update) (this actually shows the .update operation, you will need .append instead)
Adding to the dictionary (.append) (you will use this operation instead of .update from the previous link)

Filtering data (this is the final step to output the data by date)

Hope this helps, again, if you need more help don't hesitate to ask for it, just do give it a shot and try it on yourself first, then post your code here and we will help you 😉

If my answer was helpful please mark it as a solution.

View solution in original post

cives
Participant

Thanks again for the response. 

 

I tried your solution for rendering the child company's name and it didn't seem to work; I printed it both above the loop and in the loop and neither returned anything.

 

{# next begin the loop, just like for the documents #}
{% for childCompany in associated_child_companies.results %}


{# now that we are inside an associated company we need to get the associated files just like you do for the parent company #}
{% set childCompanyID = childCompany.id %}
{% set associated_child_objects = crm_associations(childCompanyID, "USER_DEFINED", 2, "&orderBy=-date_completed", "document_type,document_number,date_completed,document_url", false) %} 
{# and finally we got the documents now so we loop through them like before #}
  {{ childCompany.name }}
{% for childObject in associated_child_objects.results %} 

<tr class="mix {% for option in type.options %} {% if option.value == childObject.document_type %} {{ option.label|replace(' ','-')|lower }} {% endif %} {% endfor %}">
<td>{{ childCompany.name }}</td>

  
Regarding my second question, thank you — and I do appreciate the links to reference documents — I read through them and tried it on my own for a bit but didn't get very far; I had a difficult time figuring out how it applied to my use case.

 

I would appreciate seeing it done so that I could visualize it better; if you prefer to talk outside of this forum feel free to direct message me and thanks for everything so far.

0 Upvotes