С точки зрения покупателя, есть товары, которые нужно сложить в корзину, которую потом нужно оплатить. Но как все это выглядит внутри? Попробуем разобраться во внутреннем устройстве работы с заказами через админку Opencart.
Данные о товарах заказа хранятся в таблице order_product
, где товары с заказами связаны по id
(order_id
, product_id
). К слову информация о заказе хранится в нескольких таблицах order_
.
Перейдем в админке Продажи
-Заказы
и выберем любой заказ на редактирование.
Страница редактирования заказа состоит из 5 вкладок, в каждую из которых можно попасть только из предыдущей нажимая кнопку Продолжить
, при клике на которую на некоторых вкладках возникают ajax запросы, на основании ответов которых происходит заполнение вкладки.
Формирование заказа в админке OpenCart линейно и состоит из 5-ти последовательных этапов:
Информация о покупателе
-Товары
-Детали оплаты
-Адрес доставки
-Итого
.
Перейдем в admin/view/teplate/sale/order_form.tpl
(OpenCart 2.3). Здесь можно увидеть что изначально весь интерфейс статичный, однако при переходе на вкладку Товары
(клик по #button-customer
внутри генерирует клик #button-refresh
где и происходит изменение интерфейса) следует серия ajax запросов, в результате которых на вкладке меняется интерфейс.
Вернемся к вкладке редактирования заказа, а именно к Товары
(скрин 2 раза выше).
При попытке изменить количество позиции посылается ajax запрос с route=api/cart/add
. В файле catalog/controller/api/cart.php
в методе add
используется объект $this->cart
класса Cart
, а именно его метод add
. Если взглянуть на код метода, то не трудно понять что новые данные о товарах записываются в таблицу cart
, но нигде нет записи в таблицы order_
.
В таблице cart
есть столбец session_id
, значение которого привязывается к текущему юзеру, и является ключом данных в массиве $_SESSION
. То есть данные в таблице cart
временные и существуют только на период существования сессии юзера.
Работа с заказом через админку осуществляется через корзину - данные сохраняются в корзину (таблица
cart
), но не сохраняются в данные заказа (таблицыorder_
).
На странице редактирования заказа перейдем в последнюю вкладку Итого
, пролистаем вниз и нажмем кнопку Сохранить
.
Просматривая консоль браузера можно увидеть запрос route=api/order/edit
. Переходим в catalog/controller/api/order.php
и смотрим немаленький метод edit
, где заполняется массив order_data
данными заказа ($this->cart->getProducts()
).
Небольшой кусок кода, показывающий что данные о товарах заказа берутся из корзины:
// Products
$order_data['products'] = array();
foreach ($this->cart->getProducts() as $product) {
$option_data = array();
//...
$order_data['products'][] = array(
'product_id' => $product['product_id'],
'name' => $product['name'],
'model' => $product['model'],
'option' => $option_data,
'download' => $product['download'],
'quantity' => $product['quantity'],
'subtract' => $product['subtract'],
'price' => $product['price'],
'total' => $product['total'],
'tax' => $this->tax->getTax($product['price'], $product['tax_class_id']),
'reward' => $product['reward']
);
}
Почти в конце метода есть сохранение изменений через модель checkout/order
в таблицу order_product
:
$this->model_checkout_order->editOrder($order_id, $order_data);
А еще ниже в этом методе есть добавление истории заказа:
$this->model_checkout_order->addOrderHistory($order_id, $order_status_id);
На этом можно было бы остановится ... но дальше будет интереснее :)
Посмотрим таблицу товаров заказа order_product
:
А теперь взглянем на таблицу корзины cart
где хранятся данные редактируемого заказа:
Становится безумно интересно, как данные из корзины (cart
), сопоставляются с данными в заказе (order
)? Ведь просматривая таблицу корзины и товаров заказа между ними не видно никакой связи. Более того нет никакой связи между товарами этих двух таблиц!
На самом деле все просто, запрос сохранения заказа api/order/edit
передает:
token
по которому определяется корзинаorder_id
по которому определяется заказА теперь посмотрим внутрь модели checkout/order
в метод editOrder
и увидим там следующее:
$this->db->query("DELETE FROM " . DB_PREFIX . "order_product WHERE order_id = '" . (int)$order_id . "'");
$this->db->query("DELETE FROM " . DB_PREFIX . "order_option WHERE order_id = '" . (int)$order_id . "'");
Нет никакого сопоставления товаров из корзины с товарами из заказа: данные из заказа удаляются и записываются новые данные из корзины.
Не удобно ... но что является источником данных для заказа? Конечно корзина, а значит обновление данных корзины приводит к устареванию данных заказа.
Сохранение изменений заказа через админку осуществляется на основании данных корзины редактирования заказа, а корзина привязывается к сессии текущего администратора.
Схема не совсем очевидная, с первого взгляда может показаться запутанной. Однако, при детальном изучении становится понятна концепция, суть которой простота управления данными.