mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Collapse cancelled/no show to HubSpot's single 'Cancelled / No Show' value
'Cancelled' and 'no show' were separate strings in the outcome vocabulary, but HubSpot only ever emits the one dropdown value 'Cancelled / No Show' - so neither phantom string could ever match. Replace both with the real value (mapped to NOACCESS, best-guess pending client), which also fixes the long-standing differ mismatch: the abandonment trigger now actually fires on Cancelled / No Show. Drops the now-unused REQT enum member. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9a669dfcea
commit
4ac4dd8683
4 changed files with 11 additions and 17 deletions
|
|
@ -35,17 +35,14 @@ class UnmappableOutcomeError(Exception):
|
|||
# trigger and abandon_reason is mandatory), keyed lower-cased to match how the
|
||||
# differ compares. Only "no answer" -> CARDED is firm; the rest are best-guesses
|
||||
# pending client confirmation:
|
||||
# - "cancelled" -> REQT (Requested by Tenant; alt MYABRI92/OPTI)
|
||||
# - "no show" -> NOACCESS (No access; alt CARDED/NOADULT)
|
||||
# - "tenant refusal" -> CRA (Customer Refused Access; alt REFSURV/REFUSAL)
|
||||
# - "not viable" -> NOACCESS (No access; alt JOBD/ERROR)
|
||||
# NB "cancelled"/"no show" are our internal split of HubSpot's single
|
||||
# "Cancelled / No Show" dropdown value - the client may prefer one code for both.
|
||||
# - "cancelled / no show" -> NOACCESS (No access; alt REQT/MYABRI92 if read as
|
||||
# a tenant cancellation rather than a no-show)
|
||||
# - "tenant refusal" -> CRA (Customer Refused Access; alt REFSURV/REFUSAL)
|
||||
# - "not viable" -> NOACCESS (No access; alt JOBD/ERROR)
|
||||
# See the reason-code reference below.
|
||||
_REASON_BY_OUTCOME: dict[UnsuccessfulOutcome, AbandonReason] = {
|
||||
"no answer": AbandonReason.CARDED,
|
||||
"cancelled": AbandonReason.REQT,
|
||||
"no show": AbandonReason.NOACCESS,
|
||||
"cancelled / no show": AbandonReason.NOACCESS,
|
||||
"tenant refusal": AbandonReason.CRA,
|
||||
"not viable": AbandonReason.NOACCESS,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,12 @@ SlotCode = Literal["AM", "PM", "AD"]
|
|||
# truth shared by the abandonment trigger (etl HubspotDealDiffer) and the
|
||||
# reason-code mapping (domain.abri.abandonment).
|
||||
UnsuccessfulOutcome = Literal[
|
||||
"no answer", "cancelled", "no show", "tenant refusal", "not viable"
|
||||
"no answer", "cancelled / no show", "tenant refusal", "not viable"
|
||||
]
|
||||
|
||||
UNSUCCESSFUL_OUTCOMES: tuple[UnsuccessfulOutcome, ...] = (
|
||||
"no answer",
|
||||
"cancelled",
|
||||
"no show",
|
||||
"cancelled / no show",
|
||||
"tenant refusal",
|
||||
"not viable",
|
||||
)
|
||||
|
|
@ -35,7 +34,6 @@ class AbandonReason(str, Enum):
|
|||
CARDED = "CARDED"
|
||||
CRA = "CRA"
|
||||
NOACCESS = "NOACCESS"
|
||||
REQT = "REQT"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
|
|
|
|||
|
|
@ -1040,8 +1040,7 @@ def test_abri_deal_abandonment__outcome_not_negative__returns_false(
|
|||
"outcome",
|
||||
[
|
||||
"No Answer",
|
||||
"Cancelled",
|
||||
"No Show",
|
||||
"Cancelled / No Show",
|
||||
"Tenant Refusal",
|
||||
"Not Viable",
|
||||
"NO ANSWER",
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ def test_neither_date_leaves_the_abandonment_undated() -> None:
|
|||
("No Answer", AbandonReason.CARDED),
|
||||
("NO ANSWER", AbandonReason.CARDED),
|
||||
(" no answer ", AbandonReason.CARDED),
|
||||
("Cancelled", AbandonReason.REQT),
|
||||
("No Show", AbandonReason.NOACCESS),
|
||||
("Cancelled / No Show", AbandonReason.NOACCESS),
|
||||
("cancelled / no show", AbandonReason.NOACCESS),
|
||||
("Tenant Refusal", AbandonReason.CRA),
|
||||
(" tenant refusal ", AbandonReason.CRA),
|
||||
("Not Viable", AbandonReason.NOACCESS),
|
||||
|
|
@ -48,7 +48,7 @@ def test_a_triggering_outcome_maps_to_its_reason_code(
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
"outcome",
|
||||
[None, "", " ", "surveyed", "epc completed", "not attempted", "cancelled / no show"],
|
||||
[None, "", " ", "surveyed", "epc completed", "not attempted", "cancelled"],
|
||||
)
|
||||
def test_an_unmappable_outcome_raises(outcome: Optional[str]) -> None:
|
||||
with pytest.raises(UnmappableOutcomeError):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue