diff --git a/Changelog.md b/Changelog.md
index 629a0d2d34555744c3f4b93d6a519553b791460f..06f0b391900a03aa5f75abf8a0ee03d6df4f6ebb 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,6 +2,9 @@
 
 All notable changes to this project will be documented in this file.
 
+## [0.121] - 2024-06-17
+- DBOARD3-956: Include all Related Services contact info in TTS notification
+
 ## [0.120] - 2024-05-21
 - FIX: /poller/interfaces - Nokia snmp should be integers
 
diff --git a/inventory_provider/tasks/worker.py b/inventory_provider/tasks/worker.py
index 11900cb3a8f5b405269e4e7b38589f67d8f1ce41..82c0699cd5b44e5453e3cec646a776e5f92fcb1f 100644
--- a/inventory_provider/tasks/worker.py
+++ b/inventory_provider/tasks/worker.py
@@ -6,14 +6,13 @@ import json
 import logging
 import os
 import re
-from typing import List
 
 import ncclient.transport.errors
 from celery import Task, states, chord
 from celery.result import AsyncResult
 from celery import signals
 
-from collections import defaultdict
+from collections import defaultdict, namedtuple
 
 from kombu.exceptions import KombuError
 from lxml import etree
@@ -1271,171 +1270,211 @@ def _extract_ims_data(ims_api_url, ims_username, ims_password, verify_ssl):
     }
 
 
+def _convert_to_bits(value, unit):
+    unit = unit.lower()
+    conversions = {
+        'm': 1 << 20,
+        'mb': 1 << 20,
+        'g': 1 << 30,
+        'gbe': 1 << 30,
+    }
+    return int(value) * conversions[unit]
+
+
+def _get_speed(circuit_id, hierarchy):
+    c = hierarchy.get(circuit_id)
+    if c is None:
+        return 0
+    if c['status'] != 'operational':
+        return 0
+    pattern = re.compile(r'^(\d+)([a-zA-z]+)$')
+    m = pattern.match(c['speed'])
+    if m:
+        try:
+            return _convert_to_bits(m[1], m[2])
+        except KeyError as e:
+            logger.debug(f'Could not find key: {e} '
+                         f'for circuit: {circuit_id}')
+            return 0
+    else:
+        if c['circuit-type'] == 'service' \
+                or c['product'].lower() == 'ethernet':
+            return sum(
+                (_get_speed(x, hierarchy) for x in c['carrier-circuits'])
+            )
+        else:
+            return 0
+
+
 def transform_ims_data(data):
     locations = data['locations']
     customer_contacts = data['customer_contacts']
     planned_work_contacts = data['planned_work_contacts']
     circuit_ids_to_monitor = data['circuit_ids_to_monitor']
     additional_circuit_customers = data['additional_circuit_customers']
-    hierarchy = data['hierarchy']
-    port_id_details = data['port_id_details']
-    port_id_services = data['port_id_services']
+
+    # This is only used within this function and the populate_mic_with_third_party_data
+    # The following data gets added to this
+    #  contacts
+    #  planned_work_contacts
+    #  sid
+    #  third_party_id - only if it exists for the circuit
+    hierarchy = data['hierarchy']  # data in this gets modified
+
+    # These two just gets the flex ILS data added to them.
+    # They are also used for building interface_services
+    port_id_details = data['port_id_details']  # data in this gets modified
+    port_id_services = data['port_id_services']  # data in this gets modified
+
     circuit_ids_and_sids = data['circuit_ids_sids']
     circuit_ids_and_third_party_ids = data['circuit_ids_third_party_ids']
     geant_nodes = data['geant_nodes']
     flexils_data = data['flexils_data']
     customers = data['customers']
 
-    sid_services = defaultdict(list)
+    # this is the data that most classification data will be built from
+    # the keys are in the format hosts:interfaces
+    # e.g.
+    # MX1.FRA.DE:ET-1/0/2
+    # MX1.LON.UK:AE12
+    # MX1.LON.UK:AE12.123
+    interface_services = {}
 
-    def _get_circuit_contacts(c):
-        customer_ids = {c['customerid']}
-        customer_ids.update(
-            [ac['id'] for ac in additional_circuit_customers.get(c['id'], [])]
-        )
-        tts_contacts = set().union(
-            *[customer_contacts.get(cid, []) for cid in customer_ids])
-        pw_contacts = set().union(
-            *[planned_work_contacts.get(cid, []) for cid in customer_ids])
-        return tts_contacts, pw_contacts
-
-    for d in hierarchy.values():
-        c, ttc = _get_circuit_contacts(d)
-        d['contacts'] = sorted(list(c))
-        d['planned_work_contacts'] = sorted(list(ttc))
-        d['sid'] = circuit_ids_and_sids.get(d['id'], '')
-
-        if d['id'] in circuit_ids_and_third_party_ids:
-            d['third_party_id'] = circuit_ids_and_third_party_ids[d['id']]
-
-        # add flexils data to port_id_details and port_id_services
-        all_ils_details = flexils_data.get(d['id'])
-        if all_ils_details:
-            for ils_details in all_ils_details:
-                pid = port_id_details.get(ils_details['key'], [])
-                pid.append({
-                    'port_id': ils_details['key'],
-                    'equipment_name': ils_details['node_name'],
-                    'interface_name': ils_details['full_port_name']
-                })
-                port_id_details[ils_details['key']] = pid
-
-                pis = port_id_services.get(ils_details['key'], [])
-                pis.append({
-                    'id': d['id'],
-                    'name': d['name'],
-                    'project': d['project'],
-                    'port_a_id': ils_details['key'],
-                    'circuit_type': d['circuit-type'],
-                    'status': d['status'],
-                    'service_type': d['product'],
-                    'customerid': d['customerid'],
-                    'customer': customers.get(d['customerid'], ''),
-                    'contacts': d['contacts'],
-                    'planned_work_contacts': d['planned_work_contacts']
-                })
-                port_id_services[ils_details['key']] = pis
-
-    def _convert_to_bits(value, unit):
-        unit = unit.lower()
-        conversions = {
-            'm': 1 << 20,
-            'mb': 1 << 20,
-            'g': 1 << 30,
-            'gbe': 1 << 30,
-        }
-        return int(value) * conversions[unit]
-
-    def _get_speed(circuit_id):
-        c = hierarchy.get(circuit_id)
-        if c is None:
-            return 0
-        if c['status'] != 'operational':
-            return 0
-        pattern = re.compile(r'^(\d+)([a-zA-z]+)$')
-        m = pattern.match(c['speed'])
-        if m:
-            try:
-                return _convert_to_bits(m[1], m[2])
-            except KeyError as e:
-                logger.debug(f'Could not find key: {e} '
-                             f'for circuit: {circuit_id}')
-                return 0
-        else:
-            if c['circuit-type'] == 'service' \
-                    or c['product'].lower() == 'ethernet':
-                return sum(
-                    (_get_speed(x) for x in c['carrier-circuits'])
-                )
-            else:
-                return 0
-
-    def _get_fibre_routes(c_id):
-        _circ = hierarchy.get(c_id, None)
-        if _circ is None:
-            return
-        if _circ['speed'].lower() == 'fibre_route':
-            yield _circ['id']
-        else:
-            for cc in _circ['carrier-circuits']:
-                yield from _get_fibre_routes(cc)
-
-    def _get_related_services(circuit_id: str) -> List[dict]:
-        rs = {}
-        c = hierarchy.get(circuit_id, None)
-        if c:
-
-            if c['circuit-type'] == 'service':
-                rs[c['id']] = {
-                    'id': c['id'],
-                    'name': c['name'],
-                    'circuit_type': c['circuit-type'],
-                    'service_type': c['product'],
-                    'project': c['project'],
-                    'contacts': c['contacts'],
-                    'planned_work_contacts': c['planned_work_contacts']
+    services_by_type = {}
+    node_pair_services = {}
+    sid_services = {}
+    pop_nodes = {}
+
+    # populate pop_nodes
+    for location in locations.values():
+        pop_nodes.setdefault(location['pop']['name'], []).append(location['equipment-name'])
+
+    def _get_circuit_contacts(_circuit):
+        _customer_ids = {_circuit['customerid']}
+        _customer_ids.update(ac['id'] for ac in additional_circuit_customers.get(_circuit['id'], ()))
+
+        _trouble_ticket_contacts = set()
+        _planned_work_contacts = set()
+        for cid in _customer_ids:
+            _trouble_ticket_contacts.update(customer_contacts.get(cid, ()))
+            _planned_work_contacts.update(planned_work_contacts.get(cid, ()))
+
+        return _trouble_ticket_contacts, _planned_work_contacts
+
+    def _add_details_to_hierarchy():
+        # this updates the values in the hierarchy dict of the outer scope
+        # it is an internal function just to clearly group the logic
+        for circuit_id, hierarchy_entry in hierarchy.items():
+            # add contacts
+            tt_contacts, pw_contacts = _get_circuit_contacts(hierarchy_entry)
+            hierarchy_entry['contacts'] = sorted(tt_contacts)
+            hierarchy_entry['planned_work_contacts'] = sorted(pw_contacts)
+            # add SIDs
+            hierarchy_entry['sid'] = circuit_ids_and_sids.get(circuit_id, '')
+            # add third party ids to hierarchy - iff one exists
+            if circuit_id in circuit_ids_and_third_party_ids:
+                hierarchy_entry['third_party_id'] = circuit_ids_and_third_party_ids[circuit_id]
+
+    _add_details_to_hierarchy()
+
+    def _add_flex_ils_details_to_port_id_details(_flex_ils_details):
+        port_id_details[flex_ils_details['key']] = [{
+            'port_id': flex_ils_details['key'],
+            'equipment_name': flex_ils_details['node_name'],
+            'interface_name': flex_ils_details['full_port_name']
+        }]
+
+    def _add_flex_ils_details_to_port_id_services(_flex_ils_details, _circuit_id):
+        circuit = hierarchy[circuit_id]
+        port_id_services[flex_ils_details['key']] = [{
+            'id': circuit['id'],
+            'name': circuit['name'],
+            'project': circuit['project'],
+            'port_a_id': flex_ils_details['key'],
+            'circuit_type': circuit['circuit-type'],
+            'status': circuit['status'],
+            'service_type': circuit['product'],
+            'customerid': circuit['customerid'],
+            'customer': customers.get(circuit['customerid'], ''),
+            'contacts': circuit['contacts'],
+            'planned_work_contacts': circuit['planned_work_contacts']
+        }]
+
+    # add flex ils details to port_id_details and port_id_services
+    # flex_ils_data is a dict of circuit_ids to list of flex_ils_details
+    for circuit_id, flex_ils_details_per_circuit_id in flexils_data.items():
+        if circuit_id:  # add details iff there is a circuit (there can be a None key)
+            # an example of flex_ils_details:
+            # {'node_name': 'PAR01-MTC6-1', 'full_port_name': '5-A-1-L1-1', 'key': 'PAR01-MTC6-1:5-A-1-L1-1'}
+            for flex_ils_details in flex_ils_details_per_circuit_id:
+                _add_flex_ils_details_to_port_id_details(flex_ils_details)
+                _add_flex_ils_details_to_port_id_services(flex_ils_details, circuit_id)
+
+    def _get_related_services(_circuit_id):
+        # this may want to go outside the transform function so that it can be used
+        # by other functions, in which case we would need to also pass
+        # - hierarchy
+        # - circuit_ids_to_monitor
+        # - circuit_ids_and_sids
+
+        # using a dict as an easy way to ensure unique services
+        related_services = {}
+
+        if _circuit_id and _circuit_id in hierarchy:
+            circuit = hierarchy.get(_circuit_id, None)
+
+            if circuit['circuit-type'] == 'service':
+                related_services[circuit['id']] = {
+                    'id': circuit['id'],
+                    'name': circuit['name'],
+                    'circuit_type': circuit['circuit-type'],
+                    'service_type': circuit['product'],
+                    'project': circuit['project'],
+                    'contacts': circuit['contacts'],
+                    'planned_work_contacts': circuit['planned_work_contacts']
                 }
-                if c['id'] in circuit_ids_to_monitor:
-                    rs[c['id']]['status'] = c['status']
+                if circuit['id'] in circuit_ids_to_monitor:
+                    related_services[circuit['id']]['status'] = circuit['status']
                 else:
-                    rs[c['id']]['status'] = 'non-monitored'
-
-                if c['id'] in circuit_ids_and_sids:
-                    rs[c['id']]['sid'] = circuit_ids_and_sids[c['id']]
-
-            if c['sub-circuits']:
-                for sub in c['sub-circuits']:
-                    temp_parents = \
-                        _get_related_services(sub)
-                    rs.update({t['id']: t for t in temp_parents})
-        return list(rs.values())
-
-    def _format_service(s):
-        s['additional_customers'] = \
-            additional_circuit_customers.get(s['id'], [])
-        s['original_status'] = s['status']
-        s['monitored'] = True
-        if s['circuit_type'] == 'service' \
-                and s['id'] not in circuit_ids_to_monitor:
-            s['monitored'] = False
-            s['status'] = 'non-monitored'
-        pd_a = port_id_details[s['port_a_id']][0]
-        location_a = locations.get(pd_a['equipment_name'], None)
+                    related_services[circuit['id']]['status'] = 'non-monitored'
+
+                if circuit['id'] in circuit_ids_and_sids:
+                    related_services[circuit['id']]['sid'] = circuit_ids_and_sids[circuit['id']]
+
+            if circuit['sub-circuits']:
+                for sub_circuit_id in circuit['sub-circuits']:
+                    temp_parents = _get_related_services(sub_circuit_id)
+                    related_services.update({t['id']: t for t in temp_parents})
+        return related_services.values()
+
+    def _format_circuit(circuit):
+        circuit['additional_customers'] = additional_circuit_customers.get(circuit['id'], [])
+        circuit['original_status'] = circuit['status']
+        circuit['monitored'] = True
+        if circuit['circuit_type'] == 'service' and circuit['id'] not in circuit_ids_to_monitor:
+            circuit['monitored'] = False
+            circuit['status'] = 'non-monitored'
+
+        # there is only ever 1 item in the list, next refactor should remove the list
+        port_details_a = port_id_details[circuit['port_a_id']][0]
+        location_a = locations.get(port_details_a['equipment_name'], None)
         if location_a:
             loc_a = location_a['pop']
         else:
             loc_a = locations['UNKNOWN_LOC']['pop']
             logger.warning(
-                f'Unable to find location for {pd_a["equipment_name"]} - '
-                f'Service ID {s["id"]}')
-        s['pop_name'] = loc_a['name']
-        s['pop_abbreviation'] = loc_a['abbreviation']
-        s['equipment'] = pd_a['equipment_name']
-        s['card_id'] = ''  # this is redundant I believe
-        s['port'] = pd_a['interface_name']
-        s['logical_unit'] = ''  # this is redundant I believe
-        if 'port_b_id' in s:
-            pd_b = port_id_details[s['port_b_id']][0]
+                f'Unable to find location for {port_details_a["equipment_name"]} - '
+                f'Service ID {circuit["id"]}')
+        circuit['pop_name'] = loc_a['name']
+        circuit['pop_abbreviation'] = loc_a['abbreviation']
+        circuit['equipment'] = port_details_a['equipment_name']
+        circuit['card_id'] = ''  # this is redundant I believe
+        circuit['port'] = port_details_a['interface_name']
+        circuit['logical_unit'] = ''  # this is redundant I believe
+        if 'port_b_id' in circuit:
+
+            # there is only ever 1 item in the list, next refactor should remove the list
+            pd_b = port_id_details[circuit['port_b_id']][0]
             location_b = locations.get(pd_b['equipment_name'], None)
             if location_b:
                 loc_b = location_b['pop']
@@ -1443,76 +1482,68 @@ def transform_ims_data(data):
                 loc_b = locations['UNKNOWN_LOC']['pop']
                 logger.warning(
                     f'Unable to find location for {pd_b["equipment_name"]} - '
-                    f'Service ID {s["id"]}')
+                    f'Service ID {circuit["id"]}')
 
-            s['other_end_pop_name'] = loc_b['name']
-            s['other_end_pop_abbreviation'] = loc_b['abbreviation']
-            s['other_end_equipment'] = pd_b['equipment_name']
-            s['other_end_port'] = pd_b['interface_name']
+            circuit['other_end_pop_name'] = loc_b['name']
+            circuit['other_end_pop_abbreviation'] = loc_b['abbreviation']
+            circuit['other_end_equipment'] = pd_b['equipment_name']
+            circuit['other_end_port'] = pd_b['interface_name']
         else:
-            s['other_end_pop_name'] = ''
-            s['other_end_pop_abbreviation'] = ''
-            s['other_end_equipment'] = ''
-            s['other_end_port'] = ''
-
-        s.pop('port_a_id', None)
-        s.pop('port_b_id', None)
-
-    services_by_type = {}
-    interface_services = defaultdict(list)
-    # using a dict to ensure no duplicates
-    node_pair_services = defaultdict(dict)
-    pop_nodes = defaultdict(list)
-
-    for value in locations.values():
-        pop_nodes[value['pop']['name']].append(value['equipment-name'])
-
-    for key, value in port_id_details.items():
-        for details in value:
-            k = f"{details['equipment_name']}:" \
-                f"{details['interface_name']}"
+            circuit['other_end_pop_name'] = ''
+            circuit['other_end_pop_abbreviation'] = ''
+            circuit['other_end_equipment'] = ''
+            circuit['other_end_port'] = ''
+
+        circuit.pop('port_a_id', None)
+        circuit.pop('port_b_id', None)
+
+    # recursive function which iterates the circuit tree to find all the fibre routes
+    # the given circuit is carried by
+    def _get_fibre_routes(_circuit_id):
+        FibreRoute = namedtuple('FibreRoute', 'id name status')
+        _circuit = hierarchy.get(_circuit_id, None)
+        if _circuit is None:
+            return
+        if _circuit['speed'].lower() == 'fibre_route':
+            yield FibreRoute(_circuit['id'], _circuit['name'], _circuit['status'])
+        else:
+            for carrier_circuit_id in _circuit['carrier-circuits']:
+                yield from _get_fibre_routes(carrier_circuit_id)
+
+    def _build_interface_services():
+        for port_id, port_details in port_id_details.items():
+            _contacts = set()
+            _planned_work_contacts = set()
+            details = port_details[0]  # there is only ever 1 item in the list, next refactor should remove the list
             circuits = port_id_services.get(details['port_id'], [])
-
-            for circ in circuits:
-                # contacts, pw_contacts = _get_circuit_contacts(circ)
-                # we only want to include the Related Services contacts
-                contacts = set()
-                pw_contacts = set()
-                circ['fibre-routes'] = []
-                for x in set(_get_fibre_routes(circ['id'])):
-                    c = {
-                        'id': hierarchy[x]['id'],
-                        'name': hierarchy[x]['name'],
-                        'status': hierarchy[x]['status']
-                    }
-                    circ['fibre-routes'].append(c)
-
-                circ['related-services'] = \
-                    _get_related_services(circ['id'])
-
-                for tlc in circ['related-services']:
-                    # why were these removed?
-                    # contacts.update(tlc.pop('contacts'))
-                    if circ['status'] == 'operational' \
-                            and circ['id'] in circuit_ids_to_monitor \
-                            and tlc['status'] == 'operational' \
-                            and tlc['id'] in circuit_ids_to_monitor:
-                        contacts.update(tlc.get('contacts'))
-                        pw_contacts.update(
-                            tlc.get('planned_work_contacts', []))
-                circ['contacts'] = sorted(list(contacts))
-                circ['planned_work_contacts'] = sorted(list(pw_contacts))
-
-                circ['calculated-speed'] = _get_speed(circ['id'])
-                _format_service(circ)
-
-                type_services = services_by_type.setdefault(
-                    ims_sorted_service_type_key(circ['service_type']), dict())
-                type_services[circ['id']] = circ
-                if circ['other_end_equipment']:
-                    node_pair_services[
-                        f"{circ['equipment']}/{circ['other_end_equipment']}"
-                    ][circ['id']] = circ
+            for _circuit in circuits:
+                # add fibre routes
+                _circuit['fibre-routes'] = [fr._asdict() for fr in set(_get_fibre_routes(_circuit['id']))]
+
+                # add related services
+                _circuit['related-services'] = list(_get_related_services(_circuit['id']))
+
+                # update contact list bases on related services
+                if _circuit['status'] == 'operational':
+                    for related_service in _circuit['related-services']:
+                        if related_service['status'] == 'operational' \
+                                and related_service['id'] in circuit_ids_to_monitor:
+                            _contacts.update(related_service.get('contacts', []))
+                            _planned_work_contacts.update(related_service.get('planned_work_contacts', []))
+                _circuit['contacts'] = sorted(_contacts)
+                _circuit['planned_work_contacts'] = sorted(_planned_work_contacts)
+
+                # add speed
+                _circuit['calculated-speed'] = _get_speed(_circuit['id'], hierarchy)
+
+                # add third party ids
+                if _circuit['id'] in circuit_ids_and_third_party_ids:
+                    _circuit['third_party_id'] = circuit_ids_and_third_party_ids[_circuit['id']]
+
+                # need to do this before the sid processing as that can skip records
+                _format_circuit(_circuit)
+
+                # add sid info
                 try:
                     # get the physical port circuit, if it exists
                     # https://jira.software.geant.org/browse/POL1-687
@@ -1521,15 +1552,12 @@ def transform_ims_data(data):
                 except StopIteration:
                     port_circuit = None
 
-                if circ['id'] in circuit_ids_and_third_party_ids:
-                    circ['third_party_id'] = circuit_ids_and_third_party_ids[circ['id']]
-
                 sid = None
-                if circ['id'] in circuit_ids_and_sids:
-                    sid = circuit_ids_and_sids[circ['id']]
+                if _circuit['id'] in circuit_ids_and_sids:
+                    sid = circuit_ids_and_sids[_circuit['id']]
                 elif 'sid' in details:
                     if len(circuits) > 1:
-                        if port_circuit != circ:
+                        if port_circuit != _circuit:
                             # if this is not the physical port circuit
                             # related to this port, then we don't want to
                             # assign the SID to this circuit, so skip.
@@ -1541,26 +1569,48 @@ def transform_ims_data(data):
                 if sid is None:
                     continue
 
-                circ['sid'] = sid
-
-                sid_info = {
-                    'circuit_id': circ['id'],
-                    'sid': sid,
-                    'status': circ['original_status'],
-                    'monitored': circ['monitored'],
-                    'name': circ['name'],
-                    'speed': circ['calculated-speed'],
-                    'service_type': circ['service_type'],
-                    'project': circ['project'],
-                    'customer': circ['customer'],
-                    'equipment': circ['equipment'],
-                    'port': circ['port'],
-                    'geant_equipment': circ['equipment'] in geant_nodes
-                }
-                if sid_info not in sid_services[sid]:
-                    sid_services[sid].append(sid_info)
+                _circuit['sid'] = sid
+
+            key = f"{details['equipment_name']}:{details['interface_name']}"
+            interface_services.setdefault(key, []).extend(circuits)
+        # end of build interface_services
+
+    _build_interface_services()
+
+    def _add_to_sid_services(_circuit):
+        if 'sid' in _circuit:
+            sid = _circuit['sid']
+            sid_info = {
+                'circuit_id': _circuit['id'],
+                'sid': sid,
+                'status': _circuit['original_status'],
+                'monitored': _circuit['monitored'],
+                'name': _circuit['name'],
+                'speed': _circuit['calculated-speed'],
+                'service_type': _circuit['service_type'],
+                'project': _circuit['project'],
+                'customer': _circuit['customer'],
+                'equipment': _circuit['equipment'],
+                'port': _circuit['port'],
+                'geant_equipment': _circuit['equipment'] in geant_nodes
+            }
+            if sid_info not in sid_services.setdefault(sid, []):
+                sid_services[sid].append(sid_info)
+
+    def _add_to_services_by_type(_circuit):
+        type_key = ims_sorted_service_type_key(_circuit['service_type'])
+        services_by_type.setdefault(type_key, {})[_circuit['id']] = _circuit
+
+    def _add_to_node_pair_services(_circuit):
+        if _circuit['other_end_equipment']:
+            node_pair_key = f"{_circuit['equipment']}/{_circuit['other_end_equipment']}"
+            node_pair_services.setdefault(node_pair_key, {})[_circuit['id']] = _circuit
 
-        interface_services[k].extend(circuits)
+    for circuits in interface_services.values():
+        for circuit in circuits:
+            _add_to_sid_services(circuit)
+            _add_to_services_by_type(circuit)
+            _add_to_node_pair_services(circuit)
 
     return {
         'hierarchy': hierarchy,
@@ -1569,10 +1619,10 @@ def transform_ims_data(data):
         'node_pair_services': node_pair_services,
         'sid_services': sid_services,
         'pop_nodes': pop_nodes,
-        'locations': data['locations'],
-        'site_locations': data['site_locations'],
-        'lg_routers': data['lg_routers'],
-        'circuit_ids_to_monitor': data['circuit_ids_to_monitor'],
+        'locations': data['locations'],  # unchanged
+        'site_locations': data['site_locations'],  # unchanged and unused
+        'lg_routers': data['lg_routers'],  # unchanged and unused
+        'circuit_ids_to_monitor': data['circuit_ids_to_monitor'],  # unchanged
     }
 
 
diff --git a/setup.py b/setup.py
index 05bd083f214494897a9d14e41af5d67c0719116c..06743d87ca4e1857e235e8ec7dd2cfa3cb865cc6 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
 
 setup(
     name='inventory-provider',
-    version="0.120",
+    version="0.121",
     author='GEANT',
     author_email='swd@geant.org',
     description='Dashboard inventory provider',
diff --git a/test/test_worker.py b/test/test_worker.py
index afa1508a839621b9608fd6d385dbdc7f37b0943a..dcc32853304b2b88fefa0f7a7c47396fdd1173ff 100644
--- a/test/test_worker.py
+++ b/test/test_worker.py
@@ -211,12 +211,16 @@ def test_transform_ims_data():
 
     customer_contacts = {
         "cu_1": ["customer_1@a.org"],
-        "cu_1_1": ["customer_1_1@a.org"]
+        "cu_1_1": ["customer_1_1@a.org"],
+        "cu_sub_1": ["customer_sub_1@a.org"],
+        "cu_sub_2": ["customer_sub_2@a.org"]
     }
 
     planned_work_contacts = {
         "cu_1": ["customer_1_PW@a.org"],
-        "cu_1_1": ["customer_1_1_PW@a.org"]
+        "cu_1_1": ["customer_1_1_PW@a.org"],
+        "cu_sub_1": ["customer_sub_1_PW@a.org"],
+        "cu_sub_2": ["customer_sub_2_PW@a.org"]
     }
 
     port_id_details = {
@@ -315,7 +319,7 @@ def test_transform_ims_data():
             "project": "customer_1",
             "carrier-circuits": ["carrier_id_1"],
             "sub-circuits": ["sub_circuit_1"],
-            "customerid": "cu_1",
+            "customerid": "cu_1"
         },
         "carrier_id_1": {
             "id": "carrier_id_1",
@@ -363,7 +367,7 @@ def test_transform_ims_data():
             "project": "customer_1",
             "carrier-circuits": ["circ_id_1"],
             "sub-circuits": ["sub_circuit_2"],
-            "customerid": "cu_1",
+            "customerid": "cu_Sub_1",
         },
         "sub_circuit_2": {
             "id": "sub_circuit_2",
@@ -375,7 +379,7 @@ def test_transform_ims_data():
             "project": "customer_1",
             "carrier-circuits": ["sub_circuit_1"],
             "sub-circuits": [],
-            "customerid": "cu_1",
+            "customerid": "cu_sub_2",
         },
         702203: {
             "id": 702203,
@@ -458,12 +462,16 @@ def test_transform_ims_data():
         "CAM01-MTC6-3:1-A-1-S1-1",
         "CAM01-MTC6-3:1-A-1-L1-1"
     ]
+    assert hierarchy["circ_id_1"]["contacts"] == ["customer_1@a.org", "customer_1_1@a.org"]
+
     for v in ifs.values():
         assert len(v) == 1
         assert len(v[0]["related-services"]) == 1
         assert v[0]["related-services"][0]["id"] == "sub_circuit_2"
         assert len(v[0]["fibre-routes"]) == 1
         assert v[0]["fibre-routes"][0]["id"] == "carrier_id_3"
+        assert v[0]["contacts"] == ["customer_sub_2@a.org"]
+        assert v[0]["planned_work_contacts"] == ["customer_sub_2_PW@a.org"]
 
     nps = res["node_pair_services"]
     assert list(nps.keys()) == ["eq_a/eq_b", "eq_b/eq_a"]