Дисклеймер :
-- А давай забацаем e-commerce! Нету же e-commerce на Ларе! Ну давай забацаем!
-- Уговорил - давай забацаем! А ты не сдуешься на пол-пути?
-- Да ну! Я же могу то и это - я вообще крутой. Будет самое крутое решение в истории php!
-- Ну ок, давай начнем...
И так... начнем с самого "ничего". Как обычно происходит сделка покупки, в самом обчном супермаркете? Покупатель заходит в торовый зал, выбирает товар, проходит на кассу и оплачивает его. Он отдает деньги, получает чек, после чего он имеет право вынести товар из торгового зала. Что тут необходимо, для полного цикла? Нужно некоторое множество товаров-сущностей, оплата-сделка(процесс), и чек(сделка-сущность). Для простоты, будем считать, что корзина реализована куками на стороне клиента. То есть:
- В репозитории могут храниться товары-сущности.
- В репозитории могут храниться сделки-сущности.
- Есть некоторый процесс, который:
- создает сделку-сущность,
- связывает сделку-сущность с товарами сущностями,
- вычитает количество товаров участвовавших в сделке из репозитория,
- отправляет сделку-сущность в репозиторий
Все просто. Структура базы данных, в этом случае, будет выглядеть приблизительно так:
А теперь представим, что у нас огромное множество товаров.Чтобы хоть как-то их разграничить, мы вводим категории.К процессу сделки это прямого отношения не имеет, однако добавим эту возможность:
Часто бывает так, что товары могут относится к нескольким категориям. Например, некий копировальный аппарат, может относится как к товарам для офиса, так и к производственному печатному оборудованию. И эта особенность должна быть учтена. Необходимо ввести таблицу для many-to-many отношений:
Окей, допустим у нас может быть древовидная структура категорий. Предположим, что мы используем паттерн Closure Table, для организации древовидности, усиленный Adjacency Lists для быстрой перерисовки отношений:
А теперь допустим, что мы хотим ввести подбор-фильтр-поиск товара по параметрам. Но мы не знаем заранее, какие парметры могут быть у товара. У всех они разные. Значит нужно вывести список характеристик, в отдельную таблицу:
Но тогда, нам каждый раз нужно будет вбивать имя параметра и его значение. Кроме того, неплохо бы иметь общий список параметров чтобы выводить его для фильтрации. А значит нужно ввести еще одну таблицу, которая содержала бы этот список:
Но согласитеь, это довольно странно, если у стула можно будет указать разрешение печати, так? Значит необходимо ввести группы товаров, которые смогут иметь некоторые характеристики. Почему не привязать эти характеристики к категориям? Потому, что категории - это то, как товары представлены в каталоге, а не то, как они действительно расположены в иерархии вещей. Стоит так же отметить, что неплохо бы сделать так, чтобы товар мог принадлежать к нескольким группам, и тогда, мы могли бы просто перечислить группы, к которым относится товар. Например, назовем некоторую группу "фото-камера", и тогда в этой группе могут быть определены параметры "разрешение сенсора", "фокусное расстояние", задержка при съемке и т.д. Назовем еще одну группы "дисплей" - у него можно будет указать диагональ, разрешение, размер пиксела, задержка gtg и тому подобное. Таким образом, добавляя смартфон, мы можем указать ему группы "камера", "дисплей" и другие. И в последствии для него могут быть указаны значения этих характеристик. И так, нужно ввести группы товаров, они имеют связи many-to-many с продуктами, и параметрами:
Пришлось расположить таблицы подругому, чтобы линии связей не пересекались.
Та-а-ак. Тут вродебы закончили (на самом деле нет, ну да ладно).
Теперь вернемся к товарам. Это хорошо, что товары имеют характеристики. Но сейчас представим, что у нас есть один и тот же товар, но с разными характеристиками (параметрами). Допустим, что это магазин одежды, и одна и таже майка может быть как желтого, так и синего цвета. Создавать два отдельных товара (а на самом деле может быть и десять) не совсем верное решение. Ведь если вы захотите поправить описание этого товара, то вам придется "скакать" по всем товарам и исправлять его в каждом из них. Таким образом, мы подходим к тому, что у товаров могут быть различные варианты, и они должны быть вынесены в отдельную таблицу. И продавать мы уже будем конкретные варианты. Отделяем продукты от вариантов:
Кстати, таким образом, мы убили и второго зайца - отделили sku от article, и это хорошо, потому как это не всегда одно и тоже.
И так, все отлично - мы продаем, варианты товара и у нас все окей. А теперь представим, что наши мега-маркетологи примумали супер-акцию "два по цене трёх". Как нам быть? Создавать еще один товар или вариант товара? Это бред. Нам нужна еще абстракциия - я называю это офферами. Суть в том, что мы продаем не товары, и даже не варианты товара, а "предложения" (offers). Предложения, могут включать один или несколько товаров, и обладать политикой ценообразования. Таким образом, каждый товар в нашем каталоге на самом деле является "предложением". Если нам нужна акция "два по цене трех", то мы создаем оффер, который включает в себя два товара, и имеет ценовую политику +50% от суммарной стоимости.
Тоже самое для оффера" купи вот это и вот это и получи скидку" - в оффер добавляется два варианта и используется политика -N% от суммарной стоимости. При этом, когда оформляется сделка - она протекает как обычно: количество товаров включенных в оффер отнимается из репозитория. При этом, если количество товаров в репозитории не достаточное для комплектации в оффер - оффер считается неукомплектованным, и неотображается в каталоге. Потому как структура довольно сложная на изображении опять куча перестановок:
В большой центральной колонке сущности, относящиеся непосредственно к каталогу магазина. С лева и справа от нее - таблицы выражающие отношения или состояния сущностей. Самая правая колонка содержит сущности сделок и клиентов.
А ведь это только база каталога набросанная за час. Без логики процессов.
Так что, друг мой по имени "а-давай-забацаем-супер-движок-для-магазина", разуй глаза и делай блоги ))
@greabock , а не сохранились картинки?