logistic-node.odoo.com · saas~19.4 · прогонный лист v1

Ручнойпрогон

Четырнадцать сценариев по стенду распределённой логистики. Каждый — с посевом, шагами, ожидаемым результатом и откатом. Всё проходится от лица обычного пользователя: режим разработчика не нужен нигде, весь результат приходит всплывающим окном на экран. Порядок не случаен: карточки 09–12 идут подряд и не откатываются по одной — это одна связка failover. Стенд в исходном состоянии, ночной крон снят с расписания.

Узлов
8
Правил
160
Маршрутов
56
Сценариев
14
Крон 70
снят
ОК 0 · ПРОВАЛ 0 · ПРОПУСК 0 · ОСТАЛОСЬ 14
00 / ДО СТАРТА

Что проверить прежде всего

Четыре условия. Если хоть одно не выполнено, половина сценариев даст ложный результат — и вы будете чинить не то.

Условие 01

Обычный пользователь

Режим разработчика не нужен нигде. Все четырнадцать карточек проходятся правами кладовщика: кнопки живут в шестерёнке над списком правил, результат каждого действия приходит всплывающим окном на экран. Хватит доступа к складам.

Условие 02

Правила в авто

Все 160 правил должны быть в trigger = Автоматически. После сценариев 09–11 проверьте это ещё раз: failover намеренно переводит 20 правил в ручной режим.

Условие 03

Отпечаток исходного

Распределение маршрутов до начала: 33/40/47 — по 20, 55/69 — по 20, 62 — 19, 65 и 19 — по 1, Buy — 39. Сумма 160. К этому же состоянию стенд обязан вернуться в конце.

Условие 04

Крон не мешает

Действие «Каскад источников: ночной прогон» снято с расписания и в вашем прогоне не участвует. Проверять ничего не нужно: пока оно выключено, никто не передвинет маршруты у вас за спиной.

01 / СЦЕНАРИИ

Прогонные карточки

Отметки сохраняются в браузере — можно закрыть вкладку и вернуться. Кнопка «Выгрузить итог» кладёт в буфер текстовый отчёт со всеми отметками и заметками. Показан пользовательский путь; две служебные карточки под администратором лежат за кнопкой «+ админские» в верхней панели и в счёт прогона не идут.

A · Интерфейс
01
Представление 2770
1 мин

Паспорт узла видно на складе

В штатной Odoo склад не знает, жив он или выведен и кто его подменяет — этого просто нет в модели. Мы добавили складу три поля-«паспорта», и все дальнейшие сценарии опираются на них. Эта карточка — беглая проверка, что паспорт на месте и заполнен верно. Ничего не нажимаете, только смотрите.

Что это за поля
  • Состояние узла — жив ли склад: «Доступен», «Ограничен» (доезжает начатое, новых заявок не берёт) или «Выведен» (исключён из сети). Это выключатель, по которому работает failover.
  • Резервный узел — кто перехватывает нагрузку, если этот склад вывести. Заполнен только у хабов: WH-A подменяется WH-B и наоборот. У магазинов пуст — магазин никто не подменяет, у него меняется поставщик.
  • Приоритет источников — очередь доноров через запятую: у кого просить товар первым, у кого вторым. Для S1 это WHA,WHB — сначала центральный, если у него не хватает свободного остатка, то резервный. Это и есть «каскад источников» из сценариев 03–06.
Шаги
  1. ИнвентарьНастройкиСклады
  2. Открыть WH-A Центральный склад.
  3. Найти блок сразу после поля «Контрагент».
Ждём
  • Три поля подряд: Состояние узла = «Доступен», Резервный узел = WH-B, Приоритет источников = WHB.
  • На складе S1 Магазин Подол те же три поля, но резервный узел пуст, а приоритет = WHA,WHB.
  • У львовского S4, одесского S5 и днепровского S6 порядок обратный — WHB,WHA. Так и задумано: они ближе к резервному складу.
Если полей нет — значит, наследованное представление 2770 не применилось, и дальше идти бессмысленно: сценарии 03–12 читают именно эти поля. Остальные карточки в таком случае покажут ложный результат.
Откат

Не требуется — только чтение.

02
Представление 2771
2 мин

Служебные колонки в списке правил

Две колонки памяти спрятаны под галочку. Они понадобятся в сценариях 09–11, чтобы увидеть, что именно натворило переключение.

Шаги
  1. ИнвентарьОперацииПополнение (Replenishment)
  2. Нажать иконку настройки колонок справа в шапке таблицы.
  3. В выпадающем списке найти две новые позиции.
Ждём
  • В списке опциональных колонок есть Маршрут до failover и Приглушено failover.
  • После включения обе пусты у всех 160 строк — это и есть признак чистого исходного состояния.
Откат

Колонки можно оставить включёнными — они пригодятся дальше.

B · Каскад источников
03
Действие 935
5 мин

Первый источник справляется

Скучный случай, и именно поэтому важный: каскад не должен суетиться, когда основной узел покрывает потребность.

Посев

Правило S1 Магазин Подол / [UNV-01] Кондиціонер 12k BTU. Записать исходные значения: мин 4, макс 8, маршрут S1 ← WH-A. Выставить мин 20, макс 25. Потребность станет 19 (25 − 6 в наличии).

Шаги
  1. Отметить строку галочкой слева.
  2. Шестерёнка действийВыбрать источник по каскаду
  3. Обновить страницу и посмотреть на маршрут.
Ждём
  • Маршрут не изменился: остался S1 ← WH-A.
  • Свободного на WH-A по UNV-01 ровно 27 — потребности 19 хватает, до WH-B очередь не дошла.
Откат

Вернуть мин 4, макс 8.

04
Действие 935
5 мин

Первый не тянет — берём второй

Главный сценарий каскада. Потребность подобрана так, чтобы попасть в узкое окно между свободным остатком WH-A и WH-B.

Посев

То же правило S1 / UNV-01. Выставить мин 30, макс 35 — потребность станет 29. На WH-A свободно 27, на WH-B 30. Окно, в котором первый источник обязан отвалиться, а второй — подхватить.

Шаги
  1. Отметить строку, запустить Выбрать источник по каскаду.
  2. Прочитать всплывающее окно, не закрывая его сразу.
  3. Обновить страницу и сверить маршрут.
Ждём
  • Всплывающее окно «Каскад источников» с текстом, где видно и прежний маршрут, и новый, и числа: нужно 29, свободно 30.
  • Маршрут переключился на S1 ← WH-B.
  • Колонка «Маршрут до failover» осталась пустой — каскад не failover, свою память он не ведёт.
Внимание — вот здесь легко обмануться: каскад не запоминает прежний маршрут. Вернуть S1 ← WH-A придётся руками, и это честное ограничение, а не дефект.
Откат

Маршрут вручную на S1 ← WH-A, затем мин 4, макс 8.

05
Регресс
4 мин

Каскад не трогает закупку

Проверка на тот самый инцидент: в первом прогоне крон подменил хабам закупочный маршрут межскладским, и хабы перестали закупать у поставщика. Посев не нужен — дефициты на хабах уже есть.

Посев

Не требуется. Прямо сейчас 11 правил с ненулевой потребностью, и все они на хабах с маршрутом Buy: WH-A / UNV-01 и десять правил WH-B (ESP-01…05 и UNV-01…05).

Шаги
  1. В списке пополнения отфильтровать по складу WH-B Резервный склад.
  2. Отметить все десять строк ESP и UNV с ненулевым «К заказу».
  3. Запустить Выбрать источник по каскаду.
Ждём
  • Маршрут у всех десяти остался Buy.
  • Во всплывающем окне по строке на каждое правило: пропущено — правило не межузловое (Buy).
  • Итог по маршрутам не сдвинулся: Buy по-прежнему 39.
Если провал — это регресс той самой правки. Смотреть проверку op.route_id.supplier_wh_id в действиях 935 и 936.
Откат

Не требуется, если ждём совпало. Если маршруты поехали — вернуть все затронутые правила на Buy.

06
Состояние «ограничен»
6 мин

Ограниченный узел пропускается

Среднее состояние должно что-то значить. Узел с остатком, но «ограничен», не выбирается источником — хотя товара у него хватает.

Посев

Двойной. Первое: WH-A ▸ Состояние узла = Ограничен. Второе: правило S1 / UNV-01мин 20, макс 25 (потребность 19 — WH-A такое покрыл бы легко).

Шаги
  1. Отметить строку, запустить Выбрать источник по каскаду.
  2. Прочитать всплывающее окно, затем сверить маршрут.
Ждём
  • Маршрут ушёл на S1 ← WH-B, хотя остатка WH-A было достаточно.
  • В окне причина отказа названа прямо: WHA: не в строю (limited).
  • Ключевое: остальные 19 правил S1 не двинулись. «Ограничен» не срывает с места уже назначенное — он только не даёт выбрать себя заново.
Откат

WH-A ▸ Состояние = Доступен. Маршрут правила вручную на S1 ← WH-A. Затем мин 4, макс 8.

C · Латеральная переброска
07
Действия 936 / 937
6 мин

Донор находится среди магазинов

Переброска «магазин → магазин» мимо хабов. Донор считается по излишку сверх собственного максимума, а не по абсолютному остатку.

Посев

Правило S1 / [FST-01] Смартфон 256GB. Исходно мин 6, макс 15, в наличии 15. Выставить мин 20, макс 25 — потребность 10. У S6 Днепр лежит 60 при собственном максимуме 15, то есть излишек 45; у всех остальных магазинов ровно по 15 — излишек ноль.

Шаги
  1. Отметить строку, запустить Латеральная переброска: найти донора.
  2. Проверить маршрут и журнал.
  3. Затем запустить Отменить латерал (вернуть маршрут) на той же строке.
Ждём
  • Маршрут стал S1 ← S6 Магазин Днепр.
  • Хабы в кандидаты не попали, хотя остатка у них вдоволь: они перечислены в каскаде S1 и из латерали исключаются намеренно.
  • В колонке «Маршрут до латерала» записан прежний S1 ← WH-A.
  • После отмены маршрут вернулся сам, колонка памяти очистилась.
Откат

Действие 937 возвращает маршрут. Останется вернуть мин 6, макс 15.

08
Отказ
4 мин

Донора нет — и он молчит

Отрицательный сценарий. Действие обязано отказаться внятно, а не переставить маршрут наугад.

Посев

Правило S1 / UNV-01, мин 30, макс 35 — потребность 29. По UNV-01 во всех магазинах ровно по 6 штук при максимуме 8: излишка нет ни у кого.

Шаги
  1. Отметить строку, запустить Латеральная переброска: найти донора.
Ждём
  • Маршрут не изменился.
  • Во всплывающем окне перечислены все кандидаты с расчётом: по каждому магазину видно «свободно 6, себе 8, излишек −2», а хабы помечены как исключённые.
  • Здесь же видно ограничение «один донор на правило»: даже если бы у двух магазинов нашлось по 15, действие не сложило бы 15 + 14. Это не баг, это потолок настроечного решения.
Откат

Вернуть мин 4, макс 8.

D · Failover — связка из четырёх карточек
09
Действие 933
8 мин

Вывести WH-A из сети

Центральный сценарий стенда. Одно действие вместо примерно семидесяти ручных правок в шести разных меню.

Не откатывать — карточки 09, 10, 11 и 12 образуют одну связку. Возврат делается в карточке 11.
Посев

Не требуется. Перед запуском зафиксируйте время — понадобится, чтобы честно сравнить с ручной альтернативой.

Шаги
  1. ИнвентарьНастройкиСклады
  2. Открыть WH-A, в шестерёнке действий выбрать Вывести узел из сети (failover).
  3. Перейти в пополнение и сгруппировать список по маршруту.
Ждём
  • Состояние WH-A стало Выведен.
  • Маршруты S1 ← WH-A, S2 ← WH-A, S3 ← WH-A опустели: было по 20, стало 0.
  • Соответствующие маршруты от WH-B набрали по 20 каждый — всего 60 переключений.
  • Двадцать собственных правил WH-A ушли в trigger = Вручную, колонка «Приглушено failover» отмечена. Мёртвый склад больше не заказывает себе товар.
  • Колонка «Маршрут до failover» заполнена у всех 60 переключённых.
  • Сразу после нажатия — окно «Узел выведен из сети»: «Узел WHA выведен, нагрузка переведена на WHB. Переключено правил: 60 из 60. Приглушено собственных правил узла: 20.»
Откат

Отложен до карточки 11.

10
Защита
2 мин

Сеть нельзя обезглавить

WH-A уже выведен. Попытка вывести и WH-B оставила бы сеть без обоих хабов — действие обязано отказать.

Посев

Состояние из карточки 09: WH-A выведен, WH-B доступен и указан резервом для WH-A. Резерв самого WH-B — это WH-A.

Шаги
  1. Открыть WH-B, запустить Вывести узел из сети (failover).
Ждём
  • Красное окно с текстом вида «Резервный узел WHA сам не в строю (состояние: down)».
  • Состояние WH-B не изменилось, ни одно правило не тронуто.
Откат

Не требуется — действие ничего не записало.

11
Действие 934
6 мин

Вернуть WH-A в сеть

Возврат должен идти строго по запомненным маршрутам, а не по догадке «наверное, было от WH-A». Разница видна на S3: одно правило там сидит на межскладском маршруте изначально.

Шаги
  1. Открыть WH-A, запустить Вернуть узел в сеть.
  2. Сгруппировать пополнение по маршруту и сверить с отпечатком из условия 03.
  3. Включить обе служебные колонки и проверить, что они пусты.
Ждём
  • Окно «Узел возвращён в сеть»: восстановлено 60, возвращено в авто 20.
  • Состояние WH-A снова Доступен.
  • Распределение маршрутов в точности как в условии 03: по 20 на 33/40/47, Buy — 39, сумма 160.
  • Двадцать собственных правил WH-A вернулись в Автоматически.
  • Обе колонки памяти пусты у всех 160 строк — ни одного осиротевшего значения.
Главный критерий — не «вернулось похоже», а «вернулось ровно». Любая лишняя единица в распределении означает, что память маршрутов где-то потерялась.
Откат

Это и есть откат связки 09–11.

12
Защита
3 мин

Резерв «ограничен» — тоже не резерв

Отказ должен срабатывать не только на выведенном резерве, но и на ограниченном. Иначе среднее состояние окажется декорацией.

Посев

WH-B ▸ Состояние узла = Ограничен. Оба узла в остальном исходные.

Шаги
  1. Открыть WH-A, запустить Вывести узел из сети (failover).
Ждём
  • Отказ с текстом про состояние limited, ни одно правило не переключено.
  • WH-A остался Доступен.
Откат

WH-B ▸ Состояние = Доступен.

E · Известные ограничения — подтвердить своими глазами
13
Дробление
5 мин

Одна потребность — пять документов

Не дефект количества, а дефект формы. Количества верные; неудобен способ, которым Odoo 19 их оформляет.

Шаги
  1. Открыть товар [UNV-01] Кондиціонер 12k BTU, отчёт Прогноз, склад S3 Магазин Троещина.
  2. Раскрыть входящие перемещения и сверить их источник.
Ждём
  • Несколько отдельных документов с одним и тем же источником OP/00123.
  • Арифметика сходится: 0 в наличии + 31 входящих − 24 исходящих = прогноз 7. Переордера нет.
  • «К заказу» = 0 при остатке ниже минимума — тоже норма: прогноз уже покрыт входящими.
Почему так — модели procurement.group в saas~19.4 больше нет, поле group_id убрано и с перемещения, и с документа. Склеивать заявки одного правила в 19-й нечем; штатная замена — батчи, но это склейка на исполнении, а не единая заявка.
Откат

Не требуется — только чтение.

14
Процесс 8
6 мин

Документы не переезжают за складом

Единственный процесс, который настройкой не закрывается вообще. Убедиться в этом руками стоит до того, как закладывать его в оценку.

Посев

Любой из подтверждённых заказов S00001…S00005 — все пять оформлены на WH-A.

Шаги
  1. Открыть заказ, в «Прочей информации» сменить склад доставки на WH-B.
  2. Перейти по кнопке к связанной отгрузке.
  3. Посмотреть, с какой локации она уходит.
Ждём
  • Поле склада в заказе сменилось без ошибки.
  • Отгрузка при этом осталась на WH-A — ни тип операции, ни локация не переехали.
  • Вывод: при выводе узла из сети уже созданные документы придётся отменять и пересоздавать вручную. Это код в stock, настройкой не лечится.
Откат

Вернуть в заказе склад WH-A. Проверить, что отгрузка осталась прежней и ничего не задвоилось.

02 / СПРАВОЧНИК

Цифры под рукой

Значения сняты со стенда перед прогоном. Если они разошлись с тем, что вы видите — стенд уже кто-то двигал, и сценарии с подобранными окнами потребности перестанут работать.

Узлы
КодРезервКаскад
WHAWH-BWHB
WHBWH-AWHA
S1 ПодолWHA,WHB
S2 ОболоньWHA,WHB
S3 ТроещинаWHA,WHB
S4 ЛьвовWHB,WHA
S5 ОдессаWHB,WHA
S6 ДнепрWHB,WHA
Свободный остаток на хабах
SKUWH-A своб.WH-B своб.
UNV-0127 (из 52)30
ESP-013420
ESP-024020
ESP-053820
FST-0110560
FST-031200
UNV-046030

По UNV-01 на WH-A лежит 52, но свободно 27 — остальное зарезервировано. Каскад считает по свободному; это и делает возможным сценарий 04.

Объекты, созданные настройкой
IDТипНазваниеГде искать
19577полеstock.warehouse.x_node_stateФорма склада
19578полеstock.warehouse.x_failover_toФорма склада
19579полеstock.warehouse.x_source_priorityФорма склада
19580поле…orderpoint.x_route_before_failoverКолонка в пополнении
19585поле…orderpoint.x_route_before_lateralКолонка в пополнении
19587поле…orderpoint.x_muted_by_failoverКолонка в пополнении
2770видФорма склада: блок состоянияТехнические ▸ Представления
2771видСписок правил: две колонкиТехнические ▸ Представления
933действиеВывести узел из сети (failover)Шестерёнка на складе
934действиеВернуть узел в сетьШестерёнка на складе
935действиеВыбрать источник по каскадуШестерёнка в пополнении
936действиеЛатеральная переброска: найти донораШестерёнка в пополнении
937действиеОтменить латерал (вернуть маршрут)Шестерёнка в пополнении
70кронКаскад источников: ночной прогонЗапланированные ▸ Архивные
03 / ВОЗВРАТ

Стенд после прогона

Семь проверок. Пока все семь не сошлись, стенд считать исходным нельзя — и следующий замер сравнивать будет не с чем.

#Что сверяемНорма
1Распределение по маршрутам в пополнении33/40/47 — по 20 · 55/69 — по 20 · 62 — 19 · 65 и 19 — по 1 · Buy — 39
2Всего правил160
3Правил в trigger = Автоматически160, ни одного «Вручную»
4Состояние всех восьми узловДоступен
5Колонки «Маршрут до failover» и «до латерала»пусты у всех строк
6Колонка «Приглушено failover»снята у всех строк
7Мин/макс у правил S1 / UNV-01 и S1 / FST-014 и 8 · 6 и 15
Если что-то не сошлось — не чините вслепую. Запишите расхождение в заметку к последней карточке, которую запускали: по журналу восстанавливается, какое именно действие оставило хвост.