Задача
Закупка на яхту не помещается в обычную корзину интернет-магазина. Нужно одновременно удержать длительность рейса, число и предпочтения участников и меню на каждый день. К этому добавляются общие ингредиенты, размеры доступных упаковок, холодильник и сухие отсеки конкретной лодки, отсутствие отдельных товаров в магазине. И ещё деньги и логистика: изменение суммы после замен, разделение оплаты и точное окно доставки в марину.
Без единой системы всё это остаётся ручной работой организатора: собрать пожелания в переписке, пересчитать рецепты и порции, объединить повторяющиеся позиции, подобрать упаковки, сверить объём с возможностями яхты, оформить закупку, распределить итоговый счёт и отдельно координировать курьера. Yachtering сводит эти действия в один процесс от параметров путешествия до погрузки продуктов на борт.
Решение
Заказ как событие. Организатор начинает со страны обслуживания и языка, указывает количество людей и продолжительность, выбирает яхту и марину. У каждого параметра своя роль: страна определяет доступный каталог и поставщика, продолжительность — число дней меню, количество участников — число персональных слотов, яхта и марина — правила доставки и погрузки. Система формирует ссылку и код доступа, организатор рассылает приглашение, и у каждого участника появляются собственные запись, меню и расчёт. Организатор остаётся участником своего же события, поэтому его блюда и его доля считаются по той же модели, что и у гостей.
Свобода в границах. Участник выбирает из подготовленных альтернатив: произвольное блюдо сделало бы закупку непредсказуемой. Можно взять рыбное, мясное или растительное основное, заменить закуску на допустимый вариант, отказаться от ненужной позиции, изменить размер порции, добавить напитки, учесть пищевые ограничения и открыть состав и рецепт блюда. Любое такое решение остаётся пересчитываемым в конкретные продукты.
Из блюд в упаковки. Блюдо — отдельный тип Magento-продукта, связанный с ингредиентами через product links. Рецепт задаёт состав, количество и единицы измерения. После правки меню пересчитываются персональная корзина участника и сводная корзина события: один и тот же ингредиент из разных рецептов объединяется, масло и специи не дублируются, а требуемый вес или объём сопоставляется с фактическими розничными упаковками. Для каждой позиции отдельно хранится, какая часть упаковки уходит в рецепты. По этим долям стоимость целой пачки раскладывается между меню, которые её используют.
Вместимость яхты. Заказ проверяется по выбранной лодке и длительности тура: продукты распределяются по холодильнику, сухим шкафам, напиткам и хозяйственным отсекам, контролируется общий объём. Правила погрузки практические: охлаждённое отделяется от сухого, продукты первых дней остаются доступными, общие ингредиенты не разъезжаются по случайным коробкам. Эти данные переходят в инструкции представителю и службе доставки.
Metro и обязательный человек. После подтверждения состав заказа блокируется, и система формирует структурированный закупочный лист для Metro. Дальше включается контроль на месте: представитель сверяет собранную корзину со списком, а при отсутствии позиции подбирает замену, которая сохраняет назначение в рецепте и подходит по хранению и упаковке. Фактический состав и фактическая сумма фиксируются в системе только после проверки и становятся основанием для оплаты и бухгалтерских документов. Граница проведена намеренно: расчёт и подготовка заказа автоматизированы, а всё, что зависит от полки магазина, решает человек.
Деньги по долям. Сводный заказ хранит и общую стоимость, и долю каждого участника. Доля считается по выбранным блюдам, порциям и дополнительным товарам, а стоимость общих ингредиентов и целых упаковок распределяется между использующими их меню. Поддержаны два сценария: каждый оплачивает свою рассчитанную часть либо организатор закрывает заказ целиком и показывает остальным сумму возврата. Оформление заказа включает адреса, итоговую проверку, счёт, оплату картой через Stripe, доставку и сервисные составляющие. У участника есть отдельная страница со своей частью счёта.
Архитектура. Ядро — Magento Open Source 2.4.4. Стандартные сущности (клиенты, каталог, корзины, заказы и счета) расширены предметными модулями Event, Menu, Meal / Ingredient / Package, Pricing, Shipping / Checkout / Stripe и Import. Данные выстроены в цепочку «событие → участники → персональные меню → позиции → блюда → ингредиенты и упаковки». У каждого участника своя корзина, а главная корзина события собирает все позиции и пересчитывает итоги. Замена и удаление блюда идут через AJAX-контроллеры без перезапуска сценария. Оформление заказа собрано на Vue.js поверх фронтенда Magento, уведомления рассылают cron-процессы и почтовый модуль.
Результат
Организатор больше не диспетчер переписки: он задаёт рейс и следит за готовностью меню, остальное считает система. Участник заходит по персональной ссылке, правит только своё меню и видит собственную сумму. Чужие события ему недоступны. Представитель работает по конкретному списку с понятными правилами замены. Бухгалтерия получает итог заказа, счета и статусы оплаты в готовом виде, а доставка — марину, дату и окно, данные яхты и контакты организатора.
Операционный сценарий оформлен как последовательность состояний: setup, checkout, new/pending, processing, complete, cancelled и closed. Система хранит историю статусов, комментарии и флаги уведомлений, поэтому видно, на каком этапе событие, кто задерживает решение и какие письма уже ушли. Для разбора спорных ситуаций сохраняется вся цепочка от изменения меню до итоговой закупки, финансовой доли и доставки, и каждый её шаг можно проследить.