🐛 fix(sales): priorizar listagem de pedidos sobre follow-up de compra ativo

- impede que mensagens como 'Liste os meus pedidos' sejam consumidas pelo atalho de order_create quando ainda existe draft de compra aberto
- corrige o reaproveitamento indevido da ultima falha de credito em fluxos de vendas ativos, permitindo que a listagem siga para o handler correto
- adiciona regressao cobrindo o cenario de order_list com pending_order_drafts para evitar que a resposta fique presa no erro anterior
main
parent 65cd775b2a
commit d0c29ca374

@ -632,6 +632,8 @@ class OrquestradorService(ReviewFlowMixin, OrderFlowMixin):
normalized_message = self.normalizer.normalize_text(message).strip() normalized_message = self.normalizer.normalize_text(message).strip()
if self._looks_like_explicit_domain_shift_request(normalized_message): if self._looks_like_explicit_domain_shift_request(normalized_message):
return None return None
if self._has_order_listing_request(message):
return None
pending_order_draft = self.state.get_entry("pending_order_drafts", user_id, expire=True) pending_order_draft = self.state.get_entry("pending_order_drafts", user_id, expire=True)
if pending_order_draft: if pending_order_draft:

@ -2515,6 +2515,59 @@ class TurnDecisionContractTests(unittest.IsolatedAsyncioTestCase):
self.assertEqual(state.get_user_context(1)["active_domain"], "general") self.assertEqual(state.get_user_context(1)["active_domain"], "general")
self.assertEqual(state.get_user_context(1)["generic_memory"], {}) self.assertEqual(state.get_user_context(1)["generic_memory"], {})
async def test_active_sales_follow_up_ignores_order_listing_request_with_open_order_draft(self):
state = FakeState(
entries={
"pending_order_drafts": {
1: {
"payload": {
"cpf": "12345678909",
"vehicle_id": 15,
"modelo_veiculo": "Volkswagen T-Cross 2022",
"valor_veiculo": 73224.0,
},
"expires_at": utc_now() + timedelta(minutes=15),
}
}
},
contexts={
1: {
"active_domain": "sales",
"generic_memory": {"cpf": "12345678909"},
"shared_memory": {"cpf": "12345678909"},
"order_queue": [],
"pending_order_selection": None,
"pending_switch": None,
"last_stock_results": [
{"id": 15, "modelo": "Volkswagen T-Cross 2022", "categoria": "suv", "preco": 73224.0, "budget_relaxed": True},
],
"selected_vehicle": {"id": 15, "modelo": "Volkswagen T-Cross 2022", "categoria": "suv", "preco": 73224.0, "budget_relaxed": True},
}
}
)
service = OrquestradorService.__new__(OrquestradorService)
service.state = state
service.normalizer = EntityNormalizer()
service._get_user_context = lambda user_id: state.get_user_context(user_id)
service._save_user_context = lambda user_id, context: state.save_user_context(user_id, context)
async def fake_try_collect_and_create_order(**kwargs):
raise AssertionError("nao deveria consumir listagem de pedidos como continuacao de order_create")
service._try_collect_and_create_order = fake_try_collect_and_create_order
async def finish(response: str, queue_notice: str | None = None):
return response
response = await service._try_handle_active_sales_follow_up(
message="Liste os meus pedidos",
user_id=1,
finish=finish,
)
self.assertIsNone(response)
self.assertIsNotNone(state.get_entry("pending_order_drafts", 1))
async def test_active_sales_follow_up_allows_new_budget_search_to_reset_open_order_draft(self): async def test_active_sales_follow_up_allows_new_budget_search_to_reset_open_order_draft(self):
state = FakeState( state = FakeState(
entries={ entries={

Loading…
Cancel
Save