Skip to content

Instantly share code, notes, and snippets.

@Big-Shark
Forked from greabock/offer.md
Last active August 16, 2018 13:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Big-Shark/5bd9afb9fb613527c44f to your computer and use it in GitHub Desktop.
Save Big-Shark/5bd9afb9fb613527c44f to your computer and use it in GitHub Desktop.

#"Немного о магазинах" или "Нам нужен еще один слой абстракции"

Дисклеймер :
-- А давай забацаем e-commerce! Нету же e-commerce на Ларе! Ну давай забацаем!
-- Уговорил - давай забацаем! А ты не сдуешься на пол-пути?
-- Да ну! Я же могу то и это - я вообще крутой. Будет самое крутое решение в истории php!
-- Ну ок, давай начнем...

И так... начнем с самого "ничего". Как обычно происходит сделка покупки, в самом обчном супермаркете? Покупатель заходит в торовый зал, выбирает товар, проходит на кассу и оплачивает его. Он отдает деньги, получает чек, после чего он имеет право вынести товар из торгового зала. Что тут необходимо, для полного цикла? Нужно некоторое множество товаров-сущностей, оплата-сделка(процесс), и чек(сделка-сущность). Для простоты, будем считать, что корзина реализована куками на стороне клиента. То есть:

  1. В репозитории могут храниться товары-сущности.
  2. В репозитории могут храниться сделки-сущности.
  3. Есть некоторый процесс, который:
  4. создает сделку-сущность,
  5. связывает сделку-сущность с товарами сущностями,
  6. вычитает количество товаров участвовавших в сделке из репозитория,
  7. отправляет сделку-сущность в репозиторий

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

А теперь представим, что у нас огромное множество товаров.Чтобы хоть как-то их разграничить, мы вводим категории.К процессу сделки это прямого отношения не имеет, однако добавим эту возможность:

Часто бывает так, что товары могут относится к нескольким категориям. Например, некий копировальный аппарат, может относится как к товарам для офиса, так и к производственному печатному оборудованию. И эта особенность должна быть учтена. Необходимо ввести таблицу для many-to-many отношений:

Окей, допустим у нас может быть древовидная структура категорий. Предположим, что мы используем паттерн Closure Table, для организации древовидности, усиленный Adjacency Lists для быстрой перерисовки отношений:

А теперь допустим, что мы хотим ввести подбор-фильтр-поиск товара по параметрам. Но мы не знаем заранее, какие парметры могут быть у товара. У всех они разные. Значит нужно вывести список характеристик, в отдельную таблицу:

Но тогда, нам каждый раз нужно будет вбивать имя параметра и его значение. Кроме того, неплохо бы иметь общий список параметров чтобы выводить его для фильтрации. А значит нужно ввести еще одну таблицу, которая содержала бы этот список:

Но согласитеь, это довольно странно, если у стула можно будет указать разрешение печати, так? Значит необходимо ввести группы товаров, которые смогут иметь некоторые характеристики. Почему не привязать эти характеристики к категориям? Потому, что категории - это то, как товары представлены в каталоге, а не то, как они действительно расположены в иерархии вещей. Стоит так же отметить, что неплохо бы сделать так, чтобы товар мог принадлежать к нескольким группам, и тогда, мы могли бы просто перечислить группы, к которым относится товар. Например, назовем некоторую группу "фото-камера", и тогда в этой группе могут быть определены параметры "разрешение сенсора", "фокусное расстояние", задержка при съемке и т.д. Назовем еще одну группы "дисплей" - у него можно будет указать диагональ, разрешение, размер пиксела, задержка gtg и тому подобное. Таким образом, добавляя смартфон, мы можем указать ему группы "камера", "дисплей" и другие. И в последствии для него могут быть указаны значения этих характеристик. И так, нужно ввести группы товаров, они имеют связи many-to-many с продуктами, и параметрами:

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

Та-а-ак. Тут вродебы закончили (на самом деле нет, ну да ладно).

Теперь вернемся к товарам. Это хорошо, что товары имеют характеристики. Но сейчас представим, что у нас есть один и тот же товар, но с разными характеристиками (параметрами). Допустим, что это магазин одежды, и одна и таже майка может быть как желтого, так и синего цвета. Создавать два отдельных товара (а на самом деле может быть и десять) не совсем верное решение. Ведь если вы захотите поправить описание этого товара, то вам придется "скакать" по всем товарам и исправлять его в каждом из них. Таким образом, мы подходим к тому, что у товаров могут быть различные варианты, и они должны быть вынесены в отдельную таблицу. И продавать мы уже будем конкретные варианты. Отделяем продукты от вариантов:

Кстати, таким образом, мы убили и второго зайца - отделили sku от article, и это хорошо, потому как это не всегда одно и тоже.

И так, все отлично - мы продаем, варианты товара и у нас все окей. А теперь представим, что наши мега-маркетологи примумали супер-акцию "три по цене двух". Как нам быть? Создавать еще один товар или вариант товара? Это бред. Нам нужна еще абстракциия - я называю это офферами. Суть в том, что мы продаем не товары, и даже не варианты товара, а "предложения" (offers). Предложения, могут включать один или несколько товаров, и обладать политикой ценообразования. Таким образом, каждый товар в нашем каталоге на самом деле является "предложением". Если нам нужна акция "два по цене трех", то мы создаем оффер, который включает в себя два товара, и имеет ценовую политику +50% от суммарной стоимости. Тоже самое для оффера" купи вот это и вот это и получи скидку" - в оффер добавляется два варианта и используется политика -N% от суммарной стоимости. При этом, когда оформляется сделка - она протекает как обычно: количество товаров включенных в оффер отнимается из репозитория. При этом, если количество товаров в репозитории не достаточное для комплектации в оффер - оффер считается неукомплектованным, и неотображается в каталоге. Потому как структура довольно сложная на изображении опять куча перестановок: В большой центральной колонке сущности, относящиеся непосредственно к каталогу магазина. С лева и справа от нее - таблицы выражающие отношения или состояния сущностей. Самая правая колонка содержит сущности сделок и клиентов.

А ведь это только база каталога набросанная за час. Без логики процессов.

Так что, друг мой по имени "а-давай-забацаем-супер-движок-для-магазина", разуй глаза и делай блоги ))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment