Source code for aeat.application.review._aggregator
"""Cross-source review-queue aggregator.Provides :class:`ReviewQueue`, which combines the per-source adaptersin :mod:`aeat.application.review._adapters` into one deterministicallysorted tuple of :class:`aeat.application.review.ReviewItem` values."""from__future__importannotationsfromdecimalimportDecimalfrom...core.configimportSettingsfrom...core.loggingimportget_loggerfrom._adaptersimport(drafts_pending,invoices_pending,transactions_low_confidence,transactions_pending,)from._enumsimportReviewItemKind,ReviewState,severity_rankfrom._modelsimportReviewItem_logger=get_logger(__name__)
[docs]classReviewQueue:"""Static collector that aggregates pending review items across sources. Combines the per-source adapters (:func:`transactions_pending`, :func:`invoices_pending`, :func:`drafts_pending`) into one deterministically sorted tuple. Severity is the primary sort key; ``since`` and ``item_id`` provide stable tiebreakers. """
[docs]@staticmethoddefcollect(settings:Settings,*,bucket_id:str,kinds:frozenset[ReviewItemKind]|None=None,modelo:str|None=None,state:ReviewState=ReviewState.PENDING,confidence_below:Decimal|None=None,)->tuple[ReviewItem,...]:"""Return every pending review item that matches the filters. Args: settings: Loaded :class:`aeat.core.config.Settings`. bucket_id: Active bucket identifier used to scope the query to the correct operator profile. kinds: Optional set of :class:`ReviewItemKind` to include. ``None`` (default) means every kind. The argument is a ``frozenset`` so callers cannot mutate it after passing. modelo: Optional modelo filter. When set, items whose wrapped record has no modelo concept are excluded. state: ``ReviewState.PENDING`` (default) or ``ReviewState.ALL``. ``ALL`` returns the same set as ``PENDING`` while the adapters emit pending review items. confidence_below: Optional decision-confidence threshold. When set, the queue replaces the default transactions-pending source with :func:`transactions_low_confidence`: classified transactions whose ``classification_confidence`` is non-None and strictly less than the threshold. Other review kinds (invoices, findings) cannot satisfy a decision-confidence predicate and are excluded while this filter is active. Returns: A tuple sorted by ``(severity desc, since asc, item_id asc)``. """ifconfidence_belowisnotNone:items:list[ReviewItem]=list(transactions_low_confidence(settings,bucket_id=bucket_id,threshold=confidence_below),)else:items=[*transactions_pending(settings,bucket_id=bucket_id),*invoices_pending(settings,bucket_id=bucket_id),*drafts_pending(settings,bucket_id=bucket_id),]ifkindsisnotNone:items=[itemforiteminitemsifitem.kindinkinds]ifmodeloisnotNone:items=[itemforiteminitemsifitem.modelo==modelo]items.sort(key=lambdaitem:(-severity_rank(item.severity),item.since,item.item_id))result=tuple(items)_logger.debug("review queue collected items=%d kinds=%s modelo=%s",len(result),sorted(k.valueforkinkinds)ifkindsisnotNoneelse"all",modelo,)returnresult