83 lines
2.2 KiB
Python
83 lines
2.2 KiB
Python
"""返利班次:领表 4 起草行 / 表 3 只录协议行 → 查号 → 录协议替身 → 写表 4。"""
|
|
from __future__ import annotations
|
|
|
|
from collections import OrderedDict
|
|
from dataclasses import dataclass
|
|
from typing import Callable
|
|
|
|
from persist import (
|
|
KIND_FAIL,
|
|
AgreementOutcome,
|
|
RebateGroup,
|
|
agreement_ok,
|
|
build_found,
|
|
build_not_found,
|
|
)
|
|
from repo import Claimed
|
|
|
|
Finder = Callable[[str], bool]
|
|
Recorder = Callable[[str], AgreementOutcome]
|
|
|
|
|
|
@dataclass
|
|
class JobSummary:
|
|
claimed: int = 0
|
|
groups: int = 0
|
|
ok: int = 0
|
|
not_found: int = 0
|
|
failed: int = 0
|
|
|
|
|
|
def run_batch(
|
|
repo,
|
|
*,
|
|
finder: Finder,
|
|
recorder: Recorder,
|
|
limit: int | None = None,
|
|
) -> JobSummary:
|
|
claimed = repo.claim_pending(limit=limit)
|
|
groups = group_claimed(claimed)
|
|
summary = JobSummary(
|
|
claimed=len(claimed.drafts) + len(claimed.protocols),
|
|
groups=len(groups),
|
|
)
|
|
for group in groups:
|
|
try:
|
|
found = bool(finder(group.contract_no))
|
|
except Exception:
|
|
repo.save_group(build_not_found(group))
|
|
summary.not_found += 1
|
|
continue
|
|
if not found:
|
|
repo.save_group(build_not_found(group))
|
|
summary.not_found += 1
|
|
continue
|
|
try:
|
|
outcome = recorder(group.contract_no)
|
|
except Exception as exc:
|
|
outcome = AgreementOutcome(KIND_FAIL, None, None, str(exc))
|
|
if outcome is None:
|
|
outcome = AgreementOutcome(KIND_FAIL, None, None, "协议录入失败")
|
|
repo.save_group(build_found(group, outcome))
|
|
if agreement_ok(outcome):
|
|
summary.ok += 1
|
|
else:
|
|
summary.failed += 1
|
|
return summary
|
|
|
|
|
|
def group_claimed(claimed: Claimed) -> list[RebateGroup]:
|
|
groups: OrderedDict[str, RebateGroup] = OrderedDict()
|
|
|
|
def bucket(contract_no: str) -> RebateGroup:
|
|
number = (contract_no or "").strip()
|
|
if number not in groups:
|
|
groups[number] = RebateGroup(contract_no=number)
|
|
return groups[number]
|
|
|
|
for row in claimed.drafts:
|
|
bucket(row["contract_no"]).drafts.append(row)
|
|
for row in claimed.protocols:
|
|
bucket(row["contract_no"]).protocols.append(row)
|
|
return list(groups.values())
|