🐛 fix(review): aceitar data relativa parcial no reaproveitamento de revisao

- reconhece respostas como 'hoje' e 'amanha' no reuso do ultimo veiculo mesmo sem horario

- preserva a data-base relativa e permite completar o agendamento em uma segunda mensagem so com o horario

- adiciona teste para reaproveitamento com data relativa seguida de horario
main
parent d4271aec91
commit 943dd57d4a

@ -100,6 +100,14 @@ class ReviewFlowMixin:
continue
parts = match.groupdict()
return f"{int(parts['day']):02d}/{int(parts['month']):02d}/{int(parts['year']):04d}"
normalized_text = self._normalize_text(message).strip()
if self.normalizer.extract_hhmm_from_text(message):
return None
if "hoje" in normalized_text:
return datetime.now().strftime("%d/%m/%Y")
if "amanha" in normalized_text:
return (datetime.now() + timedelta(days=1)).strftime("%d/%m/%Y")
return None
def _merge_review_base_date_with_time(self, message: str, payload: dict) -> None:

@ -1311,6 +1311,52 @@ class ReviewFlowDraftTests(unittest.IsolatedAsyncioTestCase):
self.assertEqual(registry.calls[0][1]["data_hora"], "18/08/2026 10:00")
self.assertIn("REV-TESTE-123", final_response)
async def test_review_flow_reuses_vehicle_with_relative_date_only_and_requests_missing_time(self):
state = FakeState(
entries={
"pending_review_reuse_confirmations": {
21: {
"payload": {
"placa": "ABC1263",
"modelo": "Onix",
"ano": 2024,
"km": 50000,
"revisao_previa_concessionaria": False,
},
"expires_at": datetime.utcnow() + timedelta(minutes=30),
}
}
}
)
registry = FakeRegistry()
flow = ReviewFlowHarness(state=state, registry=registry)
today_text = datetime.now().strftime("%d/%m/%Y")
response = await flow._try_collect_and_schedule_review(
message="eu gostaria de marcar para hoje",
user_id=21,
extracted_fields={},
intents={},
turn_decision={"intent": "review_schedule", "domain": "review", "action": "collect_review_schedule"},
)
draft = state.get_entry("pending_review_drafts", 21)
self.assertIsNotNone(draft)
self.assertEqual(draft["payload"].get("data_hora_base"), today_text)
self.assertIn("Agora me informe o horario desejado", response)
final_response = await flow._try_collect_and_schedule_review(
message="as 14 horas",
user_id=21,
extracted_fields={},
intents={},
turn_decision={"intent": "review_schedule", "domain": "review", "action": "collect_review_schedule"},
)
self.assertEqual(registry.calls[0][0], "agendar_revisao")
self.assertEqual(registry.calls[0][1]["data_hora"], f"{today_text} 14:00")
self.assertIn("REV-TESTE-123", final_response)
async def test_review_flow_clears_stale_pending_confirmation_when_user_starts_new_schedule(self):
state = FakeState(
entries={

Loading…
Cancel
Save