{{ $feed->status->label() }} · обновление {{ $feed->update_interval_minutes == 720 ? '2 раза в день' : '1 раз в день' }}
{{-- Ручной импорт нужен только до первой успешной выгрузки — дальше работает автоматика. --}}
@unless ($feed->last_success_at)
@endunless
@unless ($feed->isBlocked())
@if ($isActive)
@else
@endif
@endunless
@unless ($isActive)
Фид {{ $feed->status->label() }} — его товары не показываются в каталоге. Нажмите «Включить», чтобы возобновить.
@endunless
{{-- Две выгрузки одного каталога — товары задваиваются на витрине. Предупреждаем,
но ничего не выключаем: второй фид бывает нужен, например на время переезда,
и решать это продавцу. Метку ставит проверка после импорта. --}}
@if ($feed->duplicateOf)
Похоже, эта выгрузка повторяет «{{ $feed->duplicateOf->name }}»
Совпало {{ $feed->duplicate_ratio }}% артикулов, значит одни и те же товары попадают в каталог дважды.
Если каталог один и тот же, оставьте одну выгрузку — вторую можно
открыть и сравнить.
@endif
{{-- Товар без цены на площадку не загружается. В истории импортов продавец видит
только «Пропущено», а чинится этот пропуск не в сопоставлении категорий, а в
самом файле выгрузки — поэтому говорим прямо. --}}
@if ($noPriceCount > 0)
Товаров без цены в последней выгрузке: {{ number_format($noPriceCount, 0, '', ' ') }}
На teeu товары без цены не загружаются — купить такой товар нельзя.
{{ $marketplace ? 'Укажите цену товара в кабинете '.$type->label() : 'Укажите цену в файле выгрузки' }},
и при следующем обновлении эти позиции появятся в каталоге.
@endif
{{-- Цены Wildberries отдаёт по тысяче товаров раз в 15 минут, и у большого
кабинета они собираются часами. Карточка без собранной цены в каталог не
попадает — продавец должен видеть, что это «ещё загружается», а не «пропало». --}}
@if ($pricesPending && ($pricesPending['skipped'] > 0 || $pricesPending['waiting'] > 0))
@if ($pricesPending['waiting'] > 0)
@php($hours = max(1, (int) ceil($pricesPending['waiting'] / 1000 * \App\Services\Yml\Wildberries\WildberriesPrices::INTERVAL_MINUTES / 60)))
Цены ещё загружаются: {{ number_format($pricesPending['waiting'], 0, '', ' ') }} {{ \App\Support\Ru::plural($pricesPending['waiting'], ['товар ждёт', 'товара ждут', 'товаров ждут']) }} цену
Wildberries отдаёт цены по 1000 товаров раз в 15 минут, поэтому большой каталог появляется постепенно —
примерно {{ $hours }} {{ \App\Support\Ru::plural($hours, ['час', 'часа', 'часов']) }}. Товары добавятся в каталог сами.
{{-- Окно цен у WB одно на весь кабинет: если его раз за разом занимает
другая интеграция продавца, цены не придут никогда — это надо сказать. --}}
@if ($pricesPending['limited_since']?->lt(now()->subHour()))
Но с {{ $pricesPending['limited_since']->timezone(config('app.timezone'))->format('d.m в H:i') }} Wildberries не отдаёт цены: лимит 4 запроса в час общий на весь кабинет, и его, похоже, расходует другая ваша интеграция. Проверьте, как часто учётная система или сервис аналитики запрашивают цены.
@endif
@else
Цены загружены
{{ number_format($pricesPending['skipped'], 0, '', ' ') }} {{ \App\Support\Ru::plural($pricesPending['skipped'], ['товар появится', 'товара появятся', 'товаров появятся']) }} в каталоге при ближайшем обновлении выгрузки.
@endif
@endif
{{-- У ключа маркетплейса есть срок: три месяца у Ozon, полгода у Wildberries.
Истёк — выгрузка перестаёт обновляться, а после нескольких неудач подряд
отключается и прячет товары. Узнать об этом продавец должен здесь и заранее,
а не по опустевшей витрине. --}}
@if ($marketplace && ($feed->credentialsExpired() || $feed->credentialsExpireSoon()))
@if ($feed->credentialsExpired())
{{ $type->keyName() }} {{ $type->label() }} истёк {{ $feed->credentials_expires_at->format('d.m.Y') }}
@else
{{ $type->keyName() }} {{ $type->label() }} истекает {{ $feed->credentials_expires_at->format('d.m.Y') }}
@endif
Выпустите новый {{ mb_strtolower($type->keyName()) }} в кабинете {{ $type->label() }} ({{ $type->keyPlace() }}) и вставьте его
в блоке «Кабинет {{ $type->label() }}» ниже — иначе цены и наличие перестанут обновляться.
@endif
{{-- Feed settings the seller controls. --}}
Настройки
@if ($marketplace)
{{-- Кабинет маркетплейса вместо адреса выгрузки. Сменить кабинет нельзя —
другой кабинет это другой каталог; а ключ заменить можно и нужно: у него
есть срок. Сам ключ не печатается — им управляют магазином. --}}
@php($lastRun = $feed->runs->sortByDesc('id')->first())
@php($keyWord = $type === \App\Enums\YmlSourceType::Wildberries ? 'токен' : 'ключ')
Кабинет {{ $type->label() }}
{{-- Client ID продавец Ozon узнаёт в лицо; ID продавца WB — UUID из токена, его не показываем. --}}
@if ($type === \App\Enums\YmlSourceType::Ozon)
Client ID {{ $feed->external_account_id }}
@endif
Последняя синхронизация не удалась: {{ $lastRun->error_message }}
@endif
@else
{{-- Адрес выгрузки: продавец вводит его один раз при подключении и потом
нигде не видит — а свериться с ним нужно как раз тогда, когда товары
перестали приходить. Поля для правки нет: смена адреса означает другой
каталог, и делается она через поддержку. --}}
Последняя удачная загрузка: {{ $feed->last_success_at->format('d.m.Y в H:i') }}.
@elseif ($feed->failed_sync_count > 0)
Файл по этому адресу не загружается — неудачных попыток подряд: {{ $feed->failed_sync_count }}.
@endif
@endif
@if ($marketplace)
{{-- Склады для наличия. Товар на своём складе продавец отгрузит покупателю
teeu сам, со склада маркетплейса — нет, поэтому что считать остатком,
решает он. Смена отметок пересчитывает наличие сразу, из остатков
последнего прогона. --}}
@php($selectedWarehouses = $feed->stockWarehouses())
Склады для наличия
@if ($type === \App\Enums\YmlSourceType::Wildberries)
Товар «в наличии», если на отмеченных складах есть остаток. Складов Wildberries (FBW) в списке нет: оттуда заказ с teeu не отправить. Список складов обновляется при каждой синхронизации.
@else
Товар «в наличии», если на отмеченных складах есть свободный остаток. Склады Ozon (FBO) отмечайте, только если держите такой же запас у себя: оттуда заказ с teeu не отправить. Список складов обновляется при каждой синхронизации.
@endif
@if ($feed->marketplaceWarehouses() === [])
Склады появятся после первой синхронизации.
@else
@endif
@endif
{{-- Наценка: ступени «от цены — до цены — процент». Накидывается на цены из выгрузки
(округление вверх до рубля). Пусто = цены как есть. --}}
Наценка на цены
Задайте ступени: цена товара из выгрузки попадает в подходящий диапазон, и к ней прибавляется наценка. Итог округляется вверх до рубля. Оставьте «до» пустым у последней ступени — она сработает «и выше». Без строк наценка не применяется — цены отдаются как в выгрузке. Изменения пересчитывают уже загруженные товары сразу.
{{-- Адрес склада: точка, ОТ которой считается срок доставки до города покупателя.
Правится в любой момент — оценка доставки пересчитывается автоматически. --}}
Адрес склада (откуда доставка)
Точка отгрузки товаров этого фида. От неё считается срок доставки до города покупателя. У каждого фида адрес свой — можно менять когда угодно.
{{-- Delivery zone: seller outlines where they deliver; buyers outside the zone see a badge. --}}
Зона доставки
Обведите на карте область, куда доставляете — города внутри добавятся автоматически (кликайте по карте, чтобы поставить углы; перетаскивайте угол, чтобы подвинуть; клик по углу — удалить его). Список ниже можно поправить вручную. Пусто = показываем и доставляем во все города. Покупатель из города вне зоны увидит товар с пометкой «доставка в ваш город недоступна».
Ctrl + колесо — масштаб
Определяю города…
{{-- Manual city add --}}
{{-- Selected cities: first 10, then «показать все» --}}
{{-- Category mapping: seller confirms/fixes how feed categories map to teeu (ТЗ §11). --}}
{{ $marketplace ? 'Категории '.$type->label().' → категории teeu' : 'Категории фида → категории teeu' }}
@if ($unmappedCount > 0)
Не сопоставлено: {{ $unmappedCount }} — их товары не показываются
@endif
{{-- Категорию маркетплейса часть строк находит у нас по именам, без угадывания,
— это видно в колонке «Кто». --}}
@if ($type === \App\Enums\YmlSourceType::Ozon)
Каталог teeu вырос из категорий Ozon, поэтому многие типы товаров находятся у нас по названию — такие строки отмечены «Ozon». Остальные подобраны автоматически по смыслу, их стоит проверить.
Предметы Wildberries, которые нашлись в каталоге teeu по названию, отмечены «Wildberries». Остальные подобраны автоматически по смыслу, их стоит проверить.
@endif
Товары без категории teeu не публикуются. Проверьте сопоставление: «— не показывать —» скрывает товары этой папки, а «сборная категория» подбирает категорию каждому товару по его названию — для папок вроде «Товары» или «Разное», где лежит всё подряд. Строки «подобрать не удалось» ждут вашего выбора: по ним ответ был слишком неуверенным, и мы предпочли не гадать.
Когда несколько папок идут в одну категорию, выберите её один раз и нажмите значок копирования — в остальных строках появится значок вставки.
@else
{{-- Отбор строк. Тысяча папок в одной таблице — это не «длинно», это
неработающая страница: браузер вешался на выгрузке с 3 316 строками.
По умолчанию открываем то, что ждёт решения, остальное — по запросу. --}}
{{-- Shared category list (id + breadcrumb name) for the searchable pickers. --}}
@php($catsJs = collect($teeuCategories)->map(fn ($label, $id) => ['id' => (string) $id, 'label' => $label])->values())
Скопировано:
{{-- Ответ по имени папки запоминается навсегда — в том числе ответ «не знаю».
Значит строка, не поддавшаяся однажды, сама уже не разберётся, даже когда
подбор стал точнее или в каталоге появилась нужная категория. Кнопка —
единственный способ сказать «попробуй ещё раз», и нажимает её человек:
подбор платный. --}}
@if ($unresolvedCount > 0)
@endif
@if ($savedRows !== [])
{{-- Сохранение возвращает страницу к началу, а правят её сверху вниз и
подолгу: без этого после каждого сохранения приходится заново искать
глазами, где остановился. Ведём к последней сохранённой строке. --}}
@endif
@endif