Model/domain/abri/abandonment.py
Daniel Roth 84d0e1e0d5 Date an abandonment to the deal's own dates, not now() 🟩
date_abandoned now resolves to the third failed attempt's confirmed
survey date, falling back to its last submission date, rather than the
processing date. This dates the OpenHousing cancellation to when the
job actually lapsed even if the trigger message lags or redelivers.

- domain: abandonment_date() encodes the confirmed-survey -> last-
  submission fallback
- DealAbandonment carries both dates; abandon_job raises
  AbandonmentDateUnknownError when a deal has neither
- last_submission_date now flows through the trigger message and request
- the injected clock is dropped: nothing reads now() any more

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 08:51:39 +00:00

28 lines
1.1 KiB
Python

from datetime import date
from typing import Optional
from domain.abri.models import AbandonReason
def abandonment_date(
confirmed_survey_date: Optional[date],
last_submission_date: Optional[date],
) -> Optional[date]:
"""The real-world date a deal's job is abandoned on.
The confirmed survey date of the failed third attempt, since that is when
the job actually lapsed; if no survey date was ever confirmed, the date the
third attempt was last submitted stands in. Returns None when the deal
carries neither date, leaving the caller to decide how to surface the gap.
"""
return confirmed_survey_date or last_submission_date
def abandon_reason_for_outcome(outcome: Optional[str]) -> AbandonReason:
"""The OpenHousing abandonment reason code for a HubSpot deal outcome.
The single mapping point from HubSpot's outcome to a coded reason. For now
every outcome maps to CARDED; the real outcome-to-code table is a follow-up
(needs Abri's code list), and swapping it in is a one-place change here.
"""
return AbandonReason.CARDED