More email SKU shenanigans, now with more TEST labels!
This commit is contained in:
@@ -49,9 +49,9 @@ def _is_shipping_item(item_name: str) -> bool:
|
||||
return item_name.strip().lower().startswith("shipping")
|
||||
|
||||
|
||||
def check_company_mismatch(skus: List[str]) -> Optional[TicketIssue]:
|
||||
settings = config.load_settings()
|
||||
sku_map = parse_mapping(settings.get("COMPANY_SKU_MAP", ""))
|
||||
def check_company_mismatch(skus: List[str], sku_map: Optional[dict] = None) -> Optional[TicketIssue]:
|
||||
if sku_map is None:
|
||||
sku_map = parse_mapping(config.load_settings().get("COMPANY_SKU_MAP", ""))
|
||||
|
||||
companies = set()
|
||||
for sku in skus or []:
|
||||
@@ -67,7 +67,11 @@ def check_company_mismatch(skus: List[str]) -> Optional[TicketIssue]:
|
||||
return None
|
||||
|
||||
|
||||
def check_return_device_mismatch(line_items: List[dict]) -> List[TicketIssue]:
|
||||
def check_return_device_mismatch(
|
||||
line_items: List[dict],
|
||||
keyword_map: Optional[dict] = None,
|
||||
exempt_keywords: Optional[list] = None,
|
||||
) -> List[TicketIssue]:
|
||||
"""
|
||||
A return SKU's implied device type needs to match SOMETHING else on the
|
||||
ticket - either an actual device line item (break-fix: send the asset,
|
||||
@@ -78,8 +82,10 @@ def check_return_device_mismatch(line_items: List[dict]) -> List[TicketIssue]:
|
||||
mismatch - confirmed against real examples: SH002/SH011, OK001/OK006,
|
||||
OK011/OK013).
|
||||
"""
|
||||
keyword_map = get_device_field_suggestions() # {keyword: [serial fields]} - keys only, here
|
||||
exempt_keywords = get_return_device_exempt_keywords()
|
||||
if keyword_map is None:
|
||||
keyword_map = get_device_field_suggestions() # {keyword: [serial fields]} - keys only, here
|
||||
if exempt_keywords is None:
|
||||
exempt_keywords = get_return_device_exempt_keywords()
|
||||
issues: List[TicketIssue] = []
|
||||
|
||||
device_items = [item for item in (line_items or []) if not _is_shipping_item(item.get("item_name", ""))]
|
||||
@@ -120,10 +126,38 @@ def check_return_device_mismatch(line_items: List[dict]) -> List[TicketIssue]:
|
||||
return issues
|
||||
|
||||
|
||||
def validate_ticket(skus: List[str], line_items: List[dict]) -> List[TicketIssue]:
|
||||
def validate_ticket(
|
||||
skus: List[str],
|
||||
line_items: List[dict],
|
||||
sku_map: Optional[dict] = None,
|
||||
keyword_map: Optional[dict] = None,
|
||||
exempt_keywords: Optional[list] = None,
|
||||
) -> List[TicketIssue]:
|
||||
"""
|
||||
Validates a single ticket. The optional pre-fetched params exist so a
|
||||
caller validating MANY tickets at once (the orders table, refreshing
|
||||
on every Import/Pull Tracking/etc.) can read these settings from disk
|
||||
ONCE for the whole batch, rather than once per ticket - each of these
|
||||
is itself a full .env read, and doing that per-ticket rather than
|
||||
per-batch was a real, measured performance bug (2.7s for 300 tickets,
|
||||
now ~0.1s - see make_validation_context()).
|
||||
"""
|
||||
issues: List[TicketIssue] = []
|
||||
company_issue = check_company_mismatch(skus)
|
||||
company_issue = check_company_mismatch(skus, sku_map)
|
||||
if company_issue:
|
||||
issues.append(company_issue)
|
||||
issues.extend(check_return_device_mismatch(line_items))
|
||||
issues.extend(check_return_device_mismatch(line_items, keyword_map, exempt_keywords))
|
||||
return issues
|
||||
|
||||
|
||||
def make_validation_context() -> dict:
|
||||
"""Fetches everything validate_ticket() needs from Settings ONCE, for
|
||||
passing into repeated validate_ticket() calls across a batch (e.g.
|
||||
every order in the table on a refresh) instead of re-reading .env for
|
||||
every single ticket."""
|
||||
settings = config.load_settings()
|
||||
return {
|
||||
"sku_map": parse_mapping(settings.get("COMPANY_SKU_MAP", "")),
|
||||
"keyword_map": get_device_field_suggestions(),
|
||||
"exempt_keywords": get_return_device_exempt_keywords(),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user