11import logging
2+ import json
3+ import ast
24from hubspot .crm .objects import Filter , FilterGroup , PublicObjectSearchRequest
35from hubspot .crm .properties import PropertyCreate
46from .base import get_hubspot_client
7+ from .deals import _build_dealstage_label_map
58
69# Configure logging
710logger = logging .getLogger (__name__ )
@@ -121,10 +124,64 @@ async def hubspot_search_by_property(
121124 logger .info (f"Executing hubspot_search_by_property on { object_type } : { property_name } { operator } { value } " )
122125
123126 try :
127+ # Build Filter with correct fields depending on operator
128+ filter_kwargs = {"property_name" : property_name , "operator" : operator }
129+
130+ # Operators that require no value
131+ if operator in {"HAS_PROPERTY" , "NOT_HAS_PROPERTY" }:
132+ pass
133+
134+ # Operators that require a list of values
135+ elif operator in {"IN" , "NOT_IN" }:
136+ values_list : list [str ] = []
137+ try :
138+ parsed = json .loads (value )
139+ if isinstance (parsed , list ):
140+ values_list = [str (v ) for v in parsed ]
141+ except Exception :
142+ try :
143+ parsed = ast .literal_eval (value )
144+ if isinstance (parsed , list ):
145+ values_list = [str (v ) for v in parsed ]
146+ except Exception :
147+ # Fallback: split by comma
148+ values_list = [v .strip ().strip ('"\' ' ) for v in value .split (',' ) if v .strip ()]
149+
150+ if not values_list :
151+ raise ValueError ("Operator IN/NOT_IN requires a non-empty list of values" )
152+
153+ filter_kwargs ["values" ] = values_list
154+
155+ # Between expects two endpoints: low and high
156+ elif operator == "BETWEEN" :
157+ low = None
158+ high = None
159+ try :
160+ parsed = json .loads (value )
161+ if isinstance (parsed , list ) and len (parsed ) >= 2 :
162+ low , high = str (parsed [0 ]), str (parsed [1 ])
163+ except Exception :
164+ try :
165+ parsed = ast .literal_eval (value )
166+ if isinstance (parsed , list ) and len (parsed ) >= 2 :
167+ low , high = str (parsed [0 ]), str (parsed [1 ])
168+ except Exception :
169+ pass
170+
171+ if low is None or high is None :
172+ raise ValueError ("Operator BETWEEN requires a list with two values [low, high]" )
173+
174+ filter_kwargs ["value" ] = low
175+ filter_kwargs ["high_value" ] = high
176+
177+ # All other operators use single value
178+ else :
179+ filter_kwargs ["value" ] = value
180+
124181 search_request = PublicObjectSearchRequest (
125182 filter_groups = [
126183 FilterGroup (filters = [
127- Filter (property_name = property_name , operator = operator , value = value )
184+ Filter (** filter_kwargs )
128185 ])
129186 ],
130187 properties = list (properties ),
@@ -143,6 +200,18 @@ async def hubspot_search_by_property(
143200 raise ValueError (f"Unsupported object type: { object_type } " )
144201
145202 logger .info (f"hubspot_search_by_property: Found { len (results .results )} result(s)" )
203+ # Enrich deals with human-readable dealstage label
204+ if object_type == "deals" :
205+ stage_label_map = _build_dealstage_label_map (client )
206+ enriched : list [dict ] = []
207+ for obj in results .results :
208+ props = (getattr (obj , "properties" , {}) or {}).copy ()
209+ stage_id = props .get ("dealstage" )
210+ if stage_id and stage_id in stage_label_map :
211+ props ["dealstage_label" ] = stage_label_map [stage_id ]
212+ enriched .append (props )
213+ return enriched
214+ # For other objects, return properties as-is
146215 return [obj .properties for obj in results .results ]
147216
148217 except Exception as e :
0 commit comments