@ -88,6 +88,31 @@ class ReviewFlowMixin:
if raw_model :
if raw_model :
payload [ " modelo " ] = raw_model . title ( )
payload [ " modelo " ] = raw_model . title ( )
def _extract_review_date_only_text ( self , message : str ) - > str | None :
text = self . normalizer . normalize_datetime_connector ( message )
patterns = (
r " (?<! \ d)(?P<day> \ d { 1,2})[/-](?P<month> \ d { 1,2})[/-](?P<year> \ d {4} )(?! \ s+ \ d { 1,2}: \ d {2} )(?! \ d) " ,
r " (?<! \ d)(?P<year> \ d {4} )[/-](?P<month> \ d { 1,2})[/-](?P<day> \ d { 1,2})(?! \ s+ \ d { 1,2}: \ d {2} )(?! \ d) " ,
)
for pattern in patterns :
match = re . search ( pattern , str ( text or " " ) )
if not match :
continue
parts = match . groupdict ( )
return f " { int ( parts [ ' day ' ] ) : 02d } / { int ( parts [ ' month ' ] ) : 02d } / { int ( parts [ ' year ' ] ) : 04d } "
return None
def _merge_review_base_date_with_time ( self , message : str , payload : dict ) - > None :
if not isinstance ( payload , dict ) :
return
if payload . get ( " data_hora " ) or not payload . get ( " data_hora_base " ) :
return
time_text = self . normalizer . extract_hhmm_from_text ( message )
if not time_text :
return
payload [ " data_hora " ] = f " { payload [ ' data_hora_base ' ] } { time_text } "
payload . pop ( " data_hora_base " , None )
def _infer_review_management_action (
def _infer_review_management_action (
self ,
self ,
message : str ,
message : str ,
@ -384,11 +409,29 @@ class ReviewFlowMixin:
if pending_reuse :
if pending_reuse :
should_reuse = False
should_reuse = False
date_only = self . _extract_review_date_only_text ( message )
has_explicit_time = bool ( self . normalizer . extract_hhmm_from_text ( message ) )
if date_only and not has_explicit_time :
extracted . pop ( " data_hora " , None )
if self . _is_negative_message ( message ) :
if self . _is_negative_message ( message ) :
self . state . pop_entry ( " pending_review_reuse_confirmations " , user_id )
self . state . pop_entry ( " pending_review_reuse_confirmations " , user_id )
pending_reuse = None
pending_reuse = None
if not extracted :
draft = {
" payload " : { } ,
" expires_at " : datetime . utcnow ( ) + timedelta ( minutes = PENDING_REVIEW_DRAFT_TTL_MINUTES ) ,
}
self . state . set_entry ( " pending_review_drafts " , user_id , draft )
self . _log_review_flow_source (
source = " last_review_package " ,
payload = draft [ " payload " ] ,
missing_fields = list ( REVIEW_REQUIRED_FIELDS ) ,
)
return self . _render_missing_review_fields_prompt ( list ( REVIEW_REQUIRED_FIELDS ) )
elif self . _is_affirmative_message ( message ) or " data_hora " in extracted :
elif self . _is_affirmative_message ( message ) or " data_hora " in extracted :
should_reuse = True
should_reuse = True
elif date_only :
should_reuse = True
else :
else :
self . _log_review_flow_source ( source = " last_review_package " , payload = pending_reuse . get ( " payload " ) )
self . _log_review_flow_source ( source = " last_review_package " , payload = pending_reuse . get ( " payload " ) )
return self . _render_review_reuse_question ( pending_reuse . get ( " payload " ) )
return self . _render_review_reuse_question ( pending_reuse . get ( " payload " ) )
@ -405,6 +448,15 @@ class ReviewFlowMixin:
draft [ " payload " ] . setdefault ( key , value )
draft [ " payload " ] . setdefault ( key , value )
self . state . pop_entry ( " pending_review_reuse_confirmations " , user_id )
self . state . pop_entry ( " pending_review_reuse_confirmations " , user_id )
review_flow_source = " last_review_package "
review_flow_source = " last_review_package "
if date_only and not extracted . get ( " data_hora " ) :
draft [ " payload " ] [ " data_hora_base " ] = date_only
self . state . set_entry ( " pending_review_drafts " , user_id , draft )
self . _log_review_flow_source (
source = review_flow_source ,
payload = draft [ " payload " ] ,
missing_fields = [ " data_hora " ] ,
)
return f " Perfeito. Tenho a data { date_only } . Agora me informe o horario desejado para a revisao. "
if " data_hora " not in extracted :
if " data_hora " not in extracted :
self . state . set_entry ( " pending_review_drafts " , user_id , draft )
self . state . set_entry ( " pending_review_drafts " , user_id , draft )
self . _log_review_flow_source ( source = review_flow_source , payload = draft [ " payload " ] , missing_fields = [ " data_hora " ] )
self . _log_review_flow_source ( source = review_flow_source , payload = draft [ " payload " ] , missing_fields = [ " data_hora " ] )
@ -458,7 +510,9 @@ class ReviewFlowMixin:
}
}
draft [ " payload " ] . update ( extracted )
draft [ " payload " ] . update ( extracted )
self . _merge_review_base_date_with_time ( message = message , payload = draft [ " payload " ] )
self . _supplement_review_fields_from_message ( message = message , payload = draft [ " payload " ] )
self . _supplement_review_fields_from_message ( message = message , payload = draft [ " payload " ] )
self . _merge_review_base_date_with_time ( message = message , payload = draft [ " payload " ] )
self . _try_prefill_review_fields_from_memory ( user_id = user_id , payload = draft [ " payload " ] )
self . _try_prefill_review_fields_from_memory ( user_id = user_id , payload = draft [ " payload " ] )
if (
if (
" revisao_previa_concessionaria " not in draft [ " payload " ]
" revisao_previa_concessionaria " not in draft [ " payload " ]