Мультивалютность Opencart (OCstore) | Валюта по умолчанию доллары, а отображение цен на сайте по умолчанию в рублях
- Подробности
- Категория: Opencart (OCstore)
- Обновлено 11.03.2018
Задача: Хранить в базе данных цену каждого товара в своей валюте: Товар№1=Рубли, Товар№2=Доллары, Товар№3=Евро, Товар№4=МойСобственныйКурс и т.д.
На фронт выводить цены всегда в рублях, вне зависимости от валюты товара.
И при этом пересчитывать нерублёвые цены по указанному в админке курсу.
В общем, сделать как на Virtuemart.
Тестировалось на OcStore 2
1. В таблицу oc_product базы данных добавляем поле vendor_price, которое будет хранить цену от поставщика в его валюте (например в долларах). Формат данных указываем DECIMAL(15,2)
В эту же таблицу добавляем поле currency_id для связи с таблицей oc_currency
В таблице oc_currency поле value тип данных меняем с FLOAT на DECIMAL (15,8)
2. В модели админки добавляем эти поля. В файле /admin/model/catalog/product.php
Сначала добавим функцию получения списка валют, сразу после
class ModelCatalogProduct extends Model {
public function getCurrencies() {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency");
return $query->rows;
}
Затем функция public function addProduct($data)
добавляем:
public function addProduct($data) {
$this->event->trigger('pre.admin.product.add', $data);
$this->db->query("INSERT INTO " . DB_PREFIX . "product SET
currency_id = '" . (int)$data['currency_id'] . "',
vendor_price = '" . (float)$data['vendor_price'] . "',
model = '" . $this->db->escape($data['model']) . "',
.........
после
$product_id = $this->db->getLastId();
добавляем пересчет по курсу
$this->db->query("UPDATE " . DB_PREFIX . "product JOIN " . DB_PREFIX . "currency USING(currency_id) SET price = vendor_price/value WHERE product_id = '" . (int)$product_id . "'");
функция public function editProduct($product_id, $data)
добавляем:
public function editProduct($product_id, $data) {
$this->event->trigger('pre.admin.product.edit', $data);
$this->db->query("UPDATE " . DB_PREFIX . "product SET
currency_id = '" . (int)$data['currency_id'] . "',
vendor_price = '" . (float)$data['vendor_price'] . "',
model = '" . $this->db->escape($data['model']) . "',
и ниже этого запроса добавляем пересчет по курсу
$this->db->query("UPDATE " . DB_PREFIX . "product JOIN " . DB_PREFIX . "currency USING(currency_id) SET price = vendor_price/value WHERE product_id = '" . (int)$product_id . "'");
Теперь добавим валюту в массив с продуктами public function getProducts($data = array()) {
public function getProducts($data = array()) {
$sql = "SELECT * FROM " . DB_PREFIX . "product p
LEFT JOIN " . DB_PREFIX . "currency cur USING(`currency_id`)
LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id)";
....................
3. В контроллере /admin/controller/catalog/product.php
в переменную $data['products'][] = array(
добавляем поля
$data['products'][] = array(
'product_id' => $result['product_id'],
'image' => $image,
'name' => $result['name'],
'model' => $result['model'],
'price' => $result['price'],
'currency' => $result['title'], //Название валюты
'kurs' => $result['value'], //Курс валюты
'vendor_price' => $result['vendor_price'], //Цена поставщика
'category' => $category,
.................
Далее в функции protected function getForm() {
добавляем
$data['currencies'] = $this->model_catalog_product->getCurrencies();
if (!empty($product_info)) {
$data['currency_id'] = $product_info['currency_id'];
} else {
$data['currency_id'] = '1';
}
Далее строка примерно 960
после
if (isset($this->request->post['price'])) {
$data['price'] = $this->request->post['price'];
} elseif (!empty($product_info)) {
$data['price'] = $product_info['price'];
} else {
$data['price'] = '';
}
вставляем
if (isset($this->request->post['vendor_price'])) {
$data['vendor_price'] = $this->request->post['vendor_price'];
} elseif (!empty($product_info)) {
$data['vendor_price'] = $product_info['vendor_price'];
} else {
$data['vendor_price'] = ''; }
if (isset($this->request->post['currency_id'])) {
$data['currency_id'] = $this->request->post['currency_id'];
} elseif (!empty($product_info)) {
$data['currency_id'] = $product_info['currency_id'];
} else {
$data['currency_id'] = '1'; }
4. Добавляем поля в файлах шаблонов.
Шаблон списка товаров /admin/view/template/catalog/product_list.tpl
добавляем заголовки колонок, строка примерно 112
<td class="text-left">Цена поставщика</td>
<td class="text-right">Валюта</td>
<td class="text-left">Курс</td>
и поля с данными, строка примерно 153
<td class="text-right"><?php echo $product['vendor_price'];?></td>
<td class="text-left"><?php echo $product['currency'];?></td>
<td class="text-left"><?php echo $product['kurs'];?></td>
Шаблон карточки товара /admin/view/template/catalog/product_form.tpl
Добавляем новые поля и закрываем от редактирования поле price
строка примерно 165
меняем тип на Hidden и добавим вывод рабочей цены
<div class="form-group">
<label class="col-sm-2 control-label" for="input-price"><?php echo $entry_price; ?></label>
<div class="col-sm-10">
<input type="hidden" name="price" value="<?php echo $price; ?>" placeholder="<?php echo $entry_price; ?>" id="input-price" class="form-control" />
<span><?php echo $price; ?></span>
</div>
</div>
ниже вставляем
<div class="form-group">
<label class="col-sm-2 control-label" for="input-vendor_price">Цена поставщика</label>
<div class="col-sm-10">
<input type="text" name="vendor_price" value="<?php echo $vendor_price; ?>" placeholder="0" id="input-vendor_price" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="input-currency">Валюта</label>
<div class="col-sm-10">
<select name="currency_id" id="input-currency" class="form-control">
<?php foreach ($currencies as $currency) { ?>
<?php if ($currency['currency_id'] == $currency_id) { ?>
<option value="<?php echo $currency['currency_id']; ?>" selected="selected"><?php echo $currency['title']; ?></option>
<?php } else { ?>
<option value="<?php echo $currency['currency_id']; ?>"><?php echo $currency['title']; ?></option>
<?php } ?>
<?php } ?>
</select>
</div>
</div>
Теперь при нажатии на кнопку "Сохранить" цена в базе в поле price обновится по формуле vendor_price/value
5. Осталось самое главное – пересчитать все цены по курсу. Сделать это очень просто. Нужно добавить запрос на обновление после сохранения курса в базу. Открываем файл /admin/model/localisation/currency.php
И модифицируем функцию editCurrency()
public function editCurrency($currency_id, $data) {
$this->db->query("UPDATE " . DB_PREFIX . "currency SET
title = '" . $this->db->escape($data['title']) . "',
code = '" . $this->db->escape($data['code']) . "',
symbol_left = '" . $this->db->escape($data['symbol_left']) . "',
symbol_right = '" . $this->db->escape($data['symbol_right']) . "',
decimal_place = '" . $this->db->escape($data['decimal_place']) . "',
value = '" . $this->db->escape($data['value']) . "',
status = '" . (int)$data['status'] . "',
date_modified = NOW()
WHERE currency_id = '" . (int)$currency_id . "'");
$this->db->query("UPDATE " . DB_PREFIX . "product JOIN " . DB_PREFIX . "currency USING(currency_id)
SET price = vendor_price / value WHERE currency_id = '". (int)$currency_id ."'");
$this->cache->delete('currency');
}
Цены на сайте будут меняться каждый раз, когда вы меняете значение курса. И здесь у нас открываются широкие возможности в плане курсов. Мы можем заводить свои собственные курсы, которые можно назвать наценкой. Это видно на рисунках ниже
6. Теперь смотрим список товаров в админке и нам всё понятно. Скрипт тянет курс с Yahoo и пересчитывает неправильно ЕВРО.
Исправим это недоразумение. Воспользуемся бесплатным готовым решением для получения актуальных курсов ЦБ РФ на opencartforum.com
Обратите внимание, что функция обновления валют в OpenCart-2 сменила свое название с updateCurrencies на refresh, поэтому нельзя просто заменить файл /admin/model/localisation/currency.php
Мы заменим стандартный код функции public function refresh($force = false) в модели /admin/model/localisation/currency.php
на код функции public function updateCurrencies() из готового решения.
Должно быть так:
public function refresh() {
...Здесь код из готового решения...
}
И непременно в этот файл добавляем вспомогательную функцию из того же решения:
public function CheckHttpStatus($url) {
...код функции...
}
Теперь курсы пересчитываются правильно.
Если нам нужно прибавить 2% к курсу конкретной валюты, например, только к ЕВРО, а к остальным не нужно, то в функции public function refresh() нужно добавить проверку по коду валюты и умножить значение на 1,02.
if ($result['code'] == 'EUR') { $curs = $ret[$result['code']] * 1.02; } else { $curs = $ret[$result['code']]; } $value = 1 / $curs;
На этом всё. Если возникнут вопросы, пишите.