"""NCR numbers: the form check and the link to PESCO's NCR system (pesco-ncr). An NCR number reads NCR-YYYY-NNNN (NCR-2026-0021). Q.C. gives one on a packet reject and on a rejected ITP line. """ from __future__ import annotations import re from typing import Any from ..api.errors import ApiError from ..text import LIMITS, clean_text RX_NCR = re.compile(r"^NCR-\d{4}-\d{4}$") NCR_URL = "https://ncr.pescoinc.biz/ncrs/" MSG_INVALID = "Enter an NCR number like NCR-2026-0021." NCR_MAX = LIMITS["ncr"] def validate_ncr(text: Any) -> str: """The normalised NCR number (trimmed, upper case), or 422 invalid_ncr. This is the hook for checking the number against pesco-ncr, which is a later phase. Today it accepts any well-formed number and does not look it up. """ value = clean_text(text, NCR_MAX).upper() if not RX_NCR.match(value): raise ApiError(422, "invalid_ncr", MSG_INVALID) return value def ncr_url(number: str) -> str: """The pesco-ncr page of an NCR number.""" return NCR_URL + number