Repository navigation
feat(procurement): наличие и срок поставки с сайта + честный остаток поставщиков - #848
Merged
Merged
Conversation
…поставщиков
Сайт хранит настоящие данные о наличии в мете `_remote_stock_blocks`
(`[{"warehouse":"Удалённый склад","supplier":"PRSTH","qty":2,
"lead_time_min":1,"lead_time_max":2}]`) и рендерит их в карточке как
«Наличие · В наличии · 2 шт. Срок поставки 1-2 дн.». Публичный Store API
эту мету не отдаёт, поэтому раньше казалось, что данных нет вообще.
Полный скан каталога: блок заполнен у 2 375 товаров из 30 163 (7,9 %),
срок везде 1–2 дн., склад один, поставщики CHINT/SUNWELL/AXIMA/PRSTH.
- site_adapter: `_availability()` читает блоки → `in_stock`, `stock_qty`,
`lead_time_days` (ХУДШИЙ срок из блоков — обещать быстрее нельзя),
сырые блоки в `extra`. Пустой блок → `None` («по запросу»), а не `False`.
Умолчание WooCommerce наличием по-прежнему не считается.
- suppliers: «остаток не указан» больше не превращается в «НЕТ в наличии».
Файлы остатков перечисляют только то, что ЕСТЬ (у SunWell/EKF 838
артикулов против 20 728 строк прайса), а прежнее `(stock or 0) > 0`
помечало 20 738 строк как отсутствующие без оснований — ассистент
отказывал клиенту по товарам, которые поставляются.
- OfferService._attach_supply(): позиции сайта дополняются тем, что
известно у поставщиков (18 015 из 30 163 артикулов есть в прайсах) →
«есть у поставщика — уточнить только СРОК». Имя поставщика и остаток
видит только менеджер.
- replace_source_offers(): схлопывает дубли `source_key`. Пагинация
WooCommerce (302 запроса, ~10 минут) сдвигается, если каталог меняется
на ходу, и товар попадает на две страницы — 25.09 суточный синк упал
на UNIQUE(source, source_key) и сутки остались без обновления.
- CLAUDE.md: причина нулевых цен исправлена — это НЕ вариативные товары
(все `type: simple`), и прайсами поставщиков они не покрыты.
Тесты: 19 новых (test_site_remote_stock.py, test_supplier_stock_unknown.py),
весь procurement-набор 48 passed.
## NEWS
📦 **Ассистент теперь знает сроки поставки, а не только «уточняется»**
Магазин хранил реальные остатки и сроки поставки прямо в карточках товаров —
но ассистент их не читал и про каждую позицию отвечал «наличие уточняется».
Теперь по 2 375 товарам он говорит конкретно: сколько штук есть и что срок
поставки 1–2 дня. А ещё перестал отказывать клиентам по товарам, которые
на самом деле поставляются: раньше 20 тысяч позиций из прайсов поставщиков
он ошибочно считал отсутствующими просто потому, что в файле остатков не
было строки. Теперь по таким позициям он уточняет только срок.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_remote_stock_blocks(meta_dataтовара), которую публичный Store API не показывает.site_adapter._availability()читает её →in_stock,stock_qty,lead_time_days(худший срок из блоков), сырые блоки вextra. Полный скан 30 163 товаров: блок заполнен у 2 375 (7,9 %), пуст у 27 788 («по запросу»); склад один, срок везде 1–2 дн., поставщики CHINT/SUNWELL/AXIMA/PRSTH.None, а неFalse— «по запросу» это «уточняется», а не подтверждённое отсутствие. Умолчание WooCommerce (stock_status=instockу всех 30 163,manage_stockвыключен) наличием по-прежнему не считается.(row.get("stock") or 0) > 0помечало 20 738 строк как отсутствующие без оснований, и ассистент отказывал клиенту по товарам, которые поставляются — зеркальное нарушение того же §5.5, что чинили в fix(procurement): не выдавать умолчание WooCommerce за наличие #847._attach_supply()— позиции сайта дополняются тем, что известно у поставщиков (18 015 из 30 163 артикулов каталога есть в прайсах) → «есть у поставщика — уточнить только СРОК». Имя поставщика, остаток и дату прайса видит только менеджер, клиентские каналы — нет.replace_source_offers()схлопывает дублиsource_key. Пагинация WooCommerce (302 запроса, ~10 минут) сдвигается, если каталог меняется на ходу, и товар попадает на две страницы: 25.09 синк упал наUNIQUE constraint failed: product_offers.source, product_offers.source_keyи сутки остались без обновления.type: simple), и прайсами поставщиков они не покрыты (совпадает 1 артикул из 11 378).Relates to #841
NEWS
📦 Ассистент теперь знает сроки поставки, а не только «уточняется»
Магазин хранил реальные остатки и сроки поставки прямо в карточках товаров — но ассистент их не читал и про каждую позицию отвечал «наличие уточняется». Теперь по 2 375 товарам он говорит конкретно: сколько штук есть и что срок поставки 1–2 дня. А ещё перестал отказывать клиентам по товарам, которые на самом деле поставляются: раньше 20 тысяч позиций из прайсов поставщиков он ошибочно считал отсутствующими просто потому, что в файле остатков не было строки. Теперь по таким позициям он уточняет только срок.
Test plan
pytest tests/unit/test_site_remote_stock.py— 9 тестов: заполненный блок → наличие+срок, JSON-строка, несколько складов (сумма + худший срок), пустой блок →None, отсутствие меты,stock_status=instockне наличие, явныйoutofstock→False, битый блок не падает, оффер несёт сырые блокиpytest tests/unit/test_supplier_stock_unknown.py— 10 тестов: неизвестный остаток →None, явный ноль →False, положительный →True, формулировки_supply_label(имя поставщика клиенту не утекает), аннотация позиции сайта из прайса, дубльsource_keyне роняет синкpytest tests/unit/test_offer_search_ranking.py tests/unit/test_offer_query_builder.py— регресс ранжирования зелёный (29)ruff check .+ruff format --check .— чистоFalseбыло 20 738 → стало 0 (sunwell 792/0/19936, aksima 1340/0/581, chint 1416/0/221 True/False/None)in_stock=1и непустымlead_time_days(сейчас в проде 0)🤖 Generated with Claude Code