Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

[Решено] Новая "старая" тема про НДС


Recommended Posts

Изначально, в чистом opencart, цена товара выводится либо:

1) БЕЗ НДС (например 100р) и ниже С НДС (в примере - 118р), - это если включено отображение цены с НДС, а НДС установлен 18%. 

либо

2) БЕЗ НДС ( в примере 100р)

 

Это удобно, например, для США, где цены в магазине указаны без VAT, а сам налог VAT добавляется к цене на кассе. 

 

В РФ цена товара практически всегда уже включает НДС (если товар облагается НДС), а сумма налога выделяется из итоговой суммы по формуле: НДС = Цена товара * 18/118. Ранее на форуме писали об этом, но решение не найдено (или умалчивается?)

 

Хочется вернуться к этой теме, т.к. для заказчиков юр.лиц размер ндс (и само его наличие) часто играет определяющую роль.

 

Если установить НДС равным 18%, он будет прибавляться к цене товара. Это корень проблемы, т.к. в нашем случае ндс должен вычитаться из цены, и рассчитываться по формуле (см. выше). На форуме найдено несколько решений, в т.ч. устанавливать цены на 18% ниже, а затем прибавлять к ним НДС. Но эти решения неудобны. Правильнее найти файл, в котором происходит подсчет ндс и вместо операции сложения вывести цену с ндс, а в поле tax-text выводить не "Сумма без НДС", а само значение ндс.

 

Например, нужно посчитать:

 

Товар 1

Цена с НДС 100р

НДС (включен в сумму) 15.25р

Итого 100р

 

В шаблоне карточки товара достаточно вывести

Товар 1

Цена 100р

НДС 15.25р

 

Кто подскажет, где происходит расчет налога в opencart? 

www\catalog\model\total\tax.php - это?

Надіслати
Поділитися на інших сайтах


А какой физический смысл переменной $amount ?

Вообще, как трактовать $value, $tax-rate, $amount?

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

Надіслати
Поділитися на інших сайтах


Оказывается, system/library/tax.php - это только вершина айсберга. Удалось включением/выключением отображения цен с налогом в админке выводить сумму с НДС и без НДС. для этого в tax.php сделаны следующие изменения:

  	public function calculate($value, $tax_class_id, $calculate = true) {
		if ($tax_class_id && $calculate) {
			$amount = $this->getTax($value, $tax_class_id);
				
			return $value - $amount;
		} else {
		      		return $value;
    	}
  	}

и

			if ($tax_rate['type'] == 'F') {
				$amount += $tax_rate['rate'];
			} elseif ($tax_rate['type'] == 'P') {
				$amount += $value * $tax_rate['rate']/(100 + $tax_rate['rate']);
			}

Здесь используются операторы $value, $tax_rate, $amount. По логике, $value - значение (цена товара) до обложения налогом, $tax_rate - налоговая ставка, $amount - рассчетная величина налога.  Если отталкиваться от того, что $value уже включает НДС (в России, например), то налог нужно вычесть $amount из $value Однако, ряд проблем (даже еще не все выявил) ожидают в корзине, счете и т.п.

 

В файлах шаблонов www\catalog\view\theme\default\template\product используются переменные $price и $tax, которые, по логике разработчиков выводят Цену с налогом и Цену без налога. Где и как они связаны с $amount, $tax-rate, $value я пока не нашел.

 

Предполагаю также, что разработчики вложили в понятие $amount смысл аккумулятора всех налогов, а не только НДС. Вобщем, такая внешне простая задача имеет довольно много нюансов. 

Надіслати
Поділитися на інших сайтах


Я извиняюсь, коллеги!

 

А не изобретаю я тут велосипед, случайно? Вопрос риторический, но неужели все отключили налог в админке, и счастливы? Как тогда обстоят дела с корзиной, счетом, они же добавляют ндс?

 

У меня такое предчуствие, что я не первый пришел к этому вопросу, но все почму-то помалкивают )) 

Надіслати
Поділитися на інших сайтах


Правильно ли я понимаю смысл данного тренарного выражения:

 

$tax = $this->currency->format((float)$result['special'] ? $result['special'] : $result['price']);

 

такса = спец. цене (в формате и валюте магазина), если товар иммеет признак спец.цены, иначе такса = значению price

 

??

каков тогда смысл этого:

$price = $this->currency->format($this->tax->calculate($result['price'], $result['tax_class_id'], $this->config->get('config_tax')));

 

и этого:

$special = $this->currency->format($this->tax->calculate($result['special'], $result['tax_class_id'], $this->config->get('config_tax')));

 

Тяжеловато с ООП, когда есть представления только об алгоритмических языках.  

Надіслати
Поділитися на інших сайтах


  • 2 weeks later...

Чтобы в карточке товара и каталоге отображалась цена с налогом, а под ним размер налога, делаем следующие изменения:

В файле \system\library\tax.php:

Ищем блок:

public function calculate($value, $tax_class_id, $calculate = true) {
		if ($tax_class_id && $calculate) {
			$amount = $this->getTax($value, $tax_class_id);
			return $value + $amount;
		} else {
      		return $value;
  }
}

Заменяем его на:

public function calculate($value, $tax_class_id, $calculate = true) {
		if ($tax_class_id && $calculate) {
		return $value;	
		} else {
    $amount = $this->getTax($value, $tax_class_id);
		return $value - $amount;
}
}

Смысл этой замены в том, что мы под $value будем  подразумевать стоимость одного товара с учетом ндс (а не наоборот, как задумано разработчиками), и наша задача не прибавить значение налога к сумме, а выделить его из суммы. Под $amount будем подразумевать размер налог (в валюте и формате магазина). Не путать $amount и $tax_rate! Последний – это именно процентная ставка, а $amount – конкретное значение налога для каждого конкретного товара, в рублях в нашем случае. В РФ ставка НДС=18%. Размер налога вычисляется по формуле: Цена товара * Ставку налога /(100+Ставка налога), или Цена товара*18/118. Для исправления формулы налога, находим в файле \system\library\tax.php следующий блок:

if ($tax_rate['type'] == 'F') {
				$amount += $tax_rate['rate'];
			} elseif ($tax_rate['type'] == 'P') {
				$amount += ($value / 100 * $tax_rate['rate']);
			}

И меняем его на:

if ($tax_rate['type'] == 'F') {
				$amount += $tax_rate['rate'];
			} elseif ($tax_rate['type'] == 'P') {
				$amount += ($value * $tax_rate['rate']/ (100 + $tax_rate['rate']));
			}

Если теперь в админке выбрать пункт «Отображать цены с налогом» - «Да», то будет выводится значение $value (которое у нас уже включает НДС). Если выбран чекбокс «Нет» - будет отображаться Цена без НДС (сли это вообще кому-то нужно).

 

Задача №2. Вывести значение размера налога (в рублях) в карточке товара и каталоге, вместо «Цена без НДС».

Каталог.

Для решения этой задачи перейдем к файлу  \catalog\controller\product\category.php. Найдем в нем блок:

if ((float)$result['special']) { 
…..
}

И заменим:

if ((float)$result['special']) {
					$special = $this->currency->format($this->tax->calculate($result['special'], $result['tax_class_id'], $this->config->get('config_tax')));
          $amount = $this->tax->getTax($result['special'], $result['tax_class_id']);
				} else {
					$special = false;
					$amount = $this->tax->getTax($result['price'], $result['tax_class_id']);
				}	
				
				if ($this->config->get('config_tax')) {
					$tax = $this->currency->format((float)($result['special'] ? ($result['special'] - $amount) : ($result['price'] - $amount)));
          $nds = $this->currency->format((float)($result['special'] ? $amount : $amount));
        //  echo 'tax=', $tax, '</br>';
        //  echo 'price=', $result['price']-$amount, '</br>';
        //  echo 'amount=', $amount;
				} else {
					$tax = false;
					$nds = false;
					
				}

Закомменченые строки можно удалить, они для отладки.

Добавим в массив $this->data['products'][] = array() нашу переменную ндс:

'nds'         => $nds

 

Здесь мы обращаемся к методу getTax, который возвращает значение НДС (в рублях), вводим новую переменную $nds, которую получаем из разницы цены с ндс ($price) и цены без ндс ($result[‘price’]). Заодно, корректируем значение переменной $tax, также уменьшая ее на размер налога НДС ($amount), поскольку именно $tax выводится в шаблоне как «цена без НДС». Если этого не сделать, «Цена без НДС» и «Цена» будут равны, что неверно.

Подправим шаблон категории  \catalog\view\theme\default\template\product\category.tpl

Заменим в нем блок:

<?php if ($product['tax']) { ?>
        <br />
        <span class="price-tax"><?php echo $text_tax; ?> <?php echo $product['tax']; ?></span>
        <?php } ?>
На такой:
        <?php if ($product['tax']) { ?>
        <br />
        <span class="price-tax"><?php echo 'В т.ч. НДС:' ?> <?php echo $product['nds']; ?></span>
        <?php } ?>

Я нарочно убрал   <?php echo $product['tax']; ?>, т.к. для меня эта информация бесполезна. Но можно его оставить, сделав еще одной отдельной строкой размер ндс:

 <span class="price-tax"><?php echo $text_tax; ?> <?php echo $product['tax']; ?></br><?php echo 'В т.ч. НДС:' ?> <?php echo $product['nds']; ?></span>

Карточка товара.

Аналогично, открываем файл контроллера \catalog\controller\product\product.php и меняем в нем блок:

if ((float)$product_info['special']) {
….
}

На этот:

if ((float)$product_info['special']) {
				$this->data['special'] = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')));
        $amount = $$this->tax->getTax($product_info['special'], $product_info['tax_class_id']);
			} else {
				$this->data['special'] = false;
				$amount = $this->tax->getTax($product_info['price'], $product_info['tax_class_id']);
			}
					
			if ($this->config->get('config_tax')) {
				$this->data['tax'] = $this->currency->format((float)$product_info['special'] ? ($product_info['special'] - $amount) : ($product_info['price'] - $amount));
        $this->data['nds'] = $this->currency->format((float)$product_info['special'] ? $amount : $amount);
			} else {
        $this->data['nds'] = false;
				$this->data['tax'] = false;
			}

Подправим шаблон карточки товара  \catalog\view\theme\default\template\product\product.tpl

Заменим строку:

<span class="price-tax"><?php echo $text_tax; ?> <?php echo $tax; ?></span><br />

На эту:

<span class="price-tax"><?php echo 'В т.ч. НДС:'; ?> <?php echo $nds; ?></span><br />
  • +1 5
Надіслати
Поділитися на інших сайтах


Задача №3. Вывести значение цены товара с НДС и отдельно НДС в результат поиска.

Открываем  \catalog\controller\product\search.php

Находим:

if ($this->config->get('config_tax')) {
					$tax = $this->currency->format((float)$result['special'] ? $result['special'] : $result['price']);
				} else {
					$tax = false;
				}

Меняем на :

$amount = $this->currency->format($this->tax->getTax($result['price'], $result['tax_class_id']));
				if ($this->config->get('config_tax')) {
					$tax = $this->currency->format((float)$result['special'] ? ($result['special'] - $amount) : ($result['price'] - $amount));
          $nds = $this->currency->format((float)$price - ($result['special'] ? ($result['special'] - $amount) : ($result['price'] - $amount)));
				} else {
          $nds = false;
					$tax = false;
				}

И добавим в массив $this->data['products'][] = array() нашу переменную ндс:

'nds'         => $nds

Правим шаблон \catalog\view\theme\default\template\product\search.tpl

Меняем строку:

<span class="price-tax"><?php echo $text_tax; ?> <?php echo $product['tax']; ?></span>

На эту:

<span class="price-tax"><?php echo 'В т.ч. НДС:'; ?> <?php echo $product['nds']; ?></span>

Задача №4. Скорректировать значение цены в корзине.

 

 

Чтобы в корзине не добавлялся налог к «Итого», а также правильно отображалась информация в блоке «Х товаров – ХХХХр», в файле \catalog\model\total\tax.php меняем

$total += $value;

на

$total = $total;

 

Задача №5. Корректная цена в счете.

 

Открываем \admin\controller\sale\order.php и дважды в файле заменяем строки :

'price'    => $this->currency->format($product['price'] + ($this->config->get('config_tax') ? $product['tax'] : 0), $order_info['currency_code'], $order_info['currency_value']),
						'total'    => $this->currency->format($product['total'] + ($this->config->get('config_tax') ? ($product['tax'] * $product['quantity']) : 0), $order_info['currency_code'], $order_info['currency_value'])

На эти:

'price'    => $this->currency->format($product['price'], $order_info['currency_code'], $order_info['currency_value']),
'total'    => $this->currency->format($product['total'], $order_info['currency_code'], $order_info['currency_value'])

Со стороны покупателя, в личном кабинете, счет также отображает некорректную сумму. Правим файл \catalog\controller\account\order.php Должно стать так:

'price'    => $this->currency->format($product['price'], $order_info['currency_code'], $order_info['currency_value']),
'total'    => $this->currency->format($product['total'], $order_info['currency_code'], $order_info['currency_value']),

ВСЕ!

 

П.С. Просьба не пинать, т.к. это первый опыт php5 (ООП)

Если есть желающие переделать решение для vqmod - только приветствуется. Проблем с обновлением движка тогда не будет. 

  • +1 5
Надіслати
Поділитися на інших сайтах


 

Добавим в массив $this->data['products'][] = array() нашу переменную ндс:

'nds'         => $nds

 

Здесь мы обращаемся к методу getTax, который возвращает значение НДС (в рублях), вводим новую переменную $nds, которую получаем из разницы цены с ндс ($price) и цены без ндс ($result[‘price’]). Заодно, корректируем значение переменной $tax, также уменьшая ее на размер налога НДС ($amount), поскольку именно $tax выводится в шаблоне как «цена без НДС». Если этого не сделать, «Цена без НДС» и «Цена» будут равны, что неверно.

 

Это описание производимых действий или это нужно сделать дополнительно помимо замены кода?

 

Сделал все замены до описания изменений в Карточке товара - результат следующий:

В каталоге под ценой товара - в т.ч. НДС: Notice: Undefined index: nds in/***/catalog/view/theme/default/template/product/category.tpl on line 86

 

Строка 86:

<span class="price-tax"><?php echo 'в т.ч. НДС:' ?> <?php echo $product['nds']; ?></span>

Надіслати
Поділитися на інших сайтах


Добавьте переменную $nds в массив $this->data['products'][] = array(

.......

.......

)

 

вот так должно быть:

				$this->data['products'][] = array(
					'product_id'  => $result['product_id'],
					'thumb'       => $image,
					'name'        => $result['name'],
					'description' => utf8_substr(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8')), 0, 100) . '..',
					'price'       => $price,
					'special'     => $special,
					'tax'         => $tax,
					'rating'      => $result['rating'],
					'reviews'     => sprintf($this->language->get('text_reviews'), (int)$result['reviews']),
					'href'        => $this->url->link('product/product', 'path=' . $this->request->get['path'] . '&product_id=' . $result['product_id'] . $url),
					'nds'         => $nds
				);
  • +1 3
Надіслати
Поділитися на інших сайтах


Подошел к Задаче 4. Результат предыдущих деяний:

- В каталоге НДС равен нулю

- В карточке НДС равен нулю

- В поиске НДС равен минус цене (т.е. цена 200, НДС -200)

 

Куда копать? :)

 

Прошу пардона, в файле product.php на автомате добавил переменную nds в массив, в карточке товара появилась ошибка, переменную убрал - исчез отрицательный НДС в поиске, теперь он везде равен нулю.

Надіслати
Поділитися на інших сайтах


Значит у вас $amount равен $price. Где-то в контроллере library\tax.php забыли $amount подправить.

Вообще, надо понимать, что мы принимаем за :

$value в ф-ии calculate - цена с НДС

$amount - НДС

и в шаблоне:

$price - цена с НДС

$tax - цена без НДС

 

Еще вариант - в админке должно быть Система-Настройки-Опции:

- Отображать цены с налогом: Да

- Проверка номера налога: Нет

 

Система-Локализация-Налоги-Налоговые ставки:

Название: НДС

Ставка: 18

Тип: процент

Группа покупателей: основная

Геозона: РФ

 

Ставьте в коде отладочные строки, типа:

echo '$amount = ', $amount, '</br>';

Помогает разобраться на каком этапе у вас ошибка в рассчетах.

  • +1 3
Надіслати
Поділитися на інших сайтах


 Всё получилось! Сам не осилил, попросил помощи у более опытного товарища, но дело оказалось не в сложности кода, а скорее в моей невнимательности, после указания геозоны налоги стали рассчитываться :)

 

 Классы налогов и ставки сделал как на скриншотах, поэкспериментировал и оставил в таком виде. Удобно, потому как НДС может быть и 10% (ст.164 НК РФ), а в таком виде виден налог при добавлении товара, и в Корзине покупателя.

 

 С разрешения автора могу выложить файлы с изменениями, делалось для Opencart v1.5.6.

 

 Прошу разработчиков ocStore присмотреться к этому решению и по возможности добавить его в дистрибутив, потому как этот вариант рассчитан для нашей местности :)

 

P.S. Пока не буду создавать новую тему, просто спрошу, в админке, при попытке изменить заказ покупателя, не сталкивались ли вы с синтаксической ошибкой при нажатии Добавить товар?

Классы налогов.jpg

Ставки налогов.jpg

post-674130-0-16873700-1383765500_thumb.jpg

post-674130-0-52122300-1383765500_thumb.jpg

Надіслати
Поділитися на інших сайтах


 С разрешения автора могу выложить файлы с изменениями, делалось для Opencart v1.5.6.

Не возражаю. Был удивлен, что за столько лет существования движка это не было сделано (или было?  ;) )

Решение ошибки, о которой вы упоминаете в постскрипте, я нашел пару дней назад, и создал отдельную тему:

Не вникал в суть решения. На вскидку, - не инициализированна переменная. 

Надіслати
Поділитися на інших сайтах


Файлы разложены по папкам согласно структуре Opencart. Достаточно скопировать с заменой содержимое папки Upload в папку сайта.

 

2devel

Ещё раз спасибо за помощь и подсказку :)

 

07.11.2013 12:30 перезалил файл

NDS_for_Opencart_v1.5.6.zip

NDS_for_Opencart_v1.5.6.zip

  • +1 2
Надіслати
Поділитися на інших сайтах


  • 2 months later...
  • 1 month later...

catalog/model/checkout/order.php

Еще один файл, где надо внести изменения по аналогии с \catalog\controller\account\order.php , чтобы письмо клиенту приходило с правильными цифрами. Письмо админу о заказе тоже там же формируется.

  • +1 1
Надіслати
Поділитися на інших сайтах


  • 3 weeks later...

catalog/model/checkout/order.php

Еще один файл, где надо внести изменения по аналогии с \catalog\controller\account\order.php , чтобы письмо клиенту приходило с правильными цифрами. Письмо админу о заказе тоже там же формируется.

Все верно, Дополнение по поводу письма не учел. У себя поправил, Кто ранее пользовался полным решением - рекомендуется добавить изменения, озвученные alnem

Надіслати
Поділитися на інших сайтах


  • 1 month later...
  • 4 weeks later...

Версия OpenCart 1.5.5.2

Сделал все пошагово как указано выше, НДС считает 15,25%, вместо указанных 18%.

При добавлении в переменной 'nds' => $nds  в массив $this->data['products'][] = array(

 

выдает ошибку

 

Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting ')' in Z:\home\localhost\www\domen.ru\catalog\controller\product\category.php on line 283

 

В чем может быть косяк?

 

А может у кого есть готовая сборка с исправлениями под  OpenCart 1.5.5.2 ?

Надіслати
Поділитися на інших сайтах


Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
  • Зараз на сторінці   0 користувачів

    • Ні користувачів, які переглядиють цю сторінку

×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.