Poll ETTN statuses in batches and commit per receipt #2

Merged
lauadmin merged 1 commits from feature/checkbox-ettn into main 2026-09-25 09:27:07 +00:00
Showing only changes of commit a7cba7616a - Show all commits
+18 -3
View File
@@ -68,6 +68,11 @@ _CHECKBOX_TO_STATUS = {
# или Checkbox был недоступен) и повторить его из cron'а.
_PENDING_RETRY_AFTER = timedelta(minutes=1)
# Сколько `created`-чеков опрашивать за один прогон cron'а (раз в минуту):
# при паузе ~1 с между запросами к Checkbox прогон укладывается в минуту и
# не наслаивается на следующий.
_ETTN_POLL_BATCH = 30
# Статус заказа в CRM, когда Checkbox принял ЕТТН-чек: заказ можно собирать.
CRM_STATUS_AFTER_RECEIPT = "PACKED"
# Чеки, при которых заказу нужен этот статус в CRM (Checkbox чек принял).
@@ -495,9 +500,20 @@ async def cancel_receipt(
async def sync_ettn_statuses(session: AsyncSession, client: CheckboxClient) -> None:
"""Опрашивает Checkbox по чекам, ожидающим оплаты посылки (`created`)."""
"""Опрашивает Checkbox по чекам, ожидающим оплаты посылки (`created`).
За прогон — не больше `_ETTN_POLL_BATCH` давно не проверенных чеков, с
коммитом после каждого: запросы к Checkbox идут с паузой, и опрос всех
чеков разом не укладывался в таймаут cron-задачи, а откат по таймауту
терял весь прогон — статусы не обновлялись вовсе.
"""
receipts = list(
await session.scalars(select(Receipt).where(Receipt.status == ReceiptStatus.CREATED))
await session.scalars(
select(Receipt)
.where(Receipt.status == ReceiptStatus.CREATED)
.order_by(Receipt.last_checked_at.asc().nulls_first())
.limit(_ETTN_POLL_BATCH)
)
)
registers: dict[uuid.UUID, CheckboxCredentials] = {}
for receipt in receipts:
@@ -521,7 +537,6 @@ async def sync_ettn_statuses(session: AsyncSession, client: CheckboxClient) -> N
_apply_ettn(receipt, ettn)
if receipt.status in CLOSED_STATUSES:
await _release_order(session, receipt.order_id)
await session.commit()