"""Per-operator conditional call forwarding codes (ยง5.1, M5 write-only). BiH mobile operators use standard GSM MMI codes. The dashboard shows these for the salon's assigned Gogo number; the owner dials them once on their phone. Live verification with each operator happens in the joint hardware session (HARDWARE_TESTING.md). """ from __future__ import annotations from dataclasses import dataclass OPERATORS = { "mtel": "m:tel", "bhtelecom": "BH Telecom", "eronet": "HT Eronet", } @dataclass class ForwardingCodes: operator: str operator_label: str activate_no_answer: str activate_busy: str activate_unreachable: str deactivate_all: str check_status: str def forwarding_codes(operator: str, gogo_number: str, no_answer_seconds: int = 15) -> ForwardingCodes: """Standard GSM MMI codes (same across BiH operators; kept per-operator so any operator-specific quirks found during live testing can be encoded here).""" n = gogo_number.replace(" ", "") if operator not in OPERATORS: raise ValueError(f"unknown operator: {operator}") # round to the nearest supported no-answer delay (5..30 in steps of 5) delay = min(30, max(5, 5 * round(no_answer_seconds / 5))) return ForwardingCodes( operator=operator, operator_label=OPERATORS[operator], activate_no_answer=f"**61*{n}**{delay}#", activate_busy=f"**67*{n}#", activate_unreachable=f"**62*{n}#", deactivate_all="##002#", check_status="*#61#", )