Bug: price manager adds Tax to the promotional price! Help needed...
Hi,
I think I found a bug and I ask for your help to solve it.
Basically in price manager the special discounted price is considered as “net price” even if in all other zc option has been set to display all prices including tax. So it happens that for a product that costs $100 gross, when I go to price manager and set $90 as promotional price, it displays $108 (my tax rate is 20%). That is weird… Do you have a quick fix for this?
ZC 1.3.9H.
Thank you very much for your help.
Re: Bug: price manager adds Tax to the promotional price! Help needed...
Quickest "fix" (without knowing what of it will display) is to enter 75 so that when 20% is added for display that it will display 90. Ie. Desired display price divided by (1+tax rate) such as 90/(1+0.20)=75
Re: Bug: price manager adds Tax to the promotional price! Help needed...
Quote:
Originally Posted by
mc12345678
Quickest "fix" (without knowing what of it will display) is to enter 75 so that when 20% is added for display that it will display 90. Ie. Desired display price divided by (1+tax rate) such as 90/(1+0.20)=75
That is not viable... We are working with all prives with Tax included, so to avoid mistakes there should be the possibility to set price with tax even in this field..
Re: Bug: price manager adds Tax to the promotional price! Help needed...
Quote:
Originally Posted by
ilmarchez
That is not viable... We are working with all prives with Tax included, so to avoid mistakes there should be the possibility to set price with tax even in this field..
Understand... Was looking for a "quick" fix, that was quick, not elegant, not desirable, but would allow say a single product to be so entered.
Alright, so put this together instead. Thinking it will still apply even for an old version of ZC such as 1.3.9h like you are using, but was generated from ZC 1.5.4. code, so there may be some differences.
Find this or similar code in admin/products_price_manager.php:
Code:
if ($_POST['specials_id'] != '') {
$specials_id = zen_db_prepare_input($_POST['specials_id']);
if ($_POST['products_priced_by_attribute'] == '1') {
$products_price = zen_get_products_base_price($products_filter);
} else {
$products_price = zen_db_prepare_input($_POST['products_price']);
}
$specials_price = zen_db_prepare_input($_POST['specials_price']);
if (substr($specials_price, -1) == '%') $specials_price = ($products_price - (($specials_price / 100) * $products_price));
$db->Execute("update " . TABLE_SPECIALS . " set
specials_new_products_price='" . zen_db_input($specials_price) . "',
specials_date_available='" . zen_db_input($specials_date_available) . "',
specials_last_modified=now(),
expires_date='" . zen_db_input($specials_expires_date) . "',
status='" . zen_db_input($_POST['special_status']) . "'
where products_id='" . $products_filter . "'");
}
And make it look like this:
Code:
if ($_POST['specials_id'] != '') {
$specials_id = zen_db_prepare_input($_POST['specials_id']);
if ($_POST['products_priced_by_attribute'] == '1') {
$products_price = zen_get_products_base_price($products_filter);
} else {
$products_price = zen_db_prepare_input($_POST['products_price']);
}
$specials_price = zen_db_prepare_input($_POST['specials_price']);
if (substr($specials_price, -1) == '%') $specials_price = ($products_price - (($specials_price / 100) * $products_price));
if (DISPLAY_PRICE_WITH_TAX == 'true') {
$taxRate = zen_get_tax_rate($_POST['products_tax_class_id']);
if ($taxRate > 0) {
$specials_price = $specials_price / (($taxRate / 100) + 1);
}
}
$db->Execute("update " . TABLE_SPECIALS . " set
specials_new_products_price='" . zen_db_input($specials_price) . "',
specials_date_available='" . zen_db_input($specials_date_available) . "',
specials_last_modified=now(),
expires_date='" . zen_db_input($specials_expires_date) . "',
status='" . zen_db_input($_POST['special_status']) . "'
where products_id='" . $products_filter . "'");
}
Untested, may be buggy, but looks like it might work... Could modify things to be more like the standard product entry field in the product description, but hadn't gone to find all the associated code to do the auto calculations, etc... New code added in blue.
Re: Bug: price manager adds Tax to the promotional price! Help needed...
It worked! Thank you so much!!!!
I have one final issue, I'd appreciate so much your help...
I have the addon dual pricing and customers are divided into customers and wholesalers.
Wholesalers should display prices without taxes
Customers should display prices with taxes
To make this happen I've modified the code as follows:
- in the includes/functions/functions_taxes.php I changed this code:
Code:
function zen_add_tax($price, $tax) {
global $currencies;
if ( (DISPLAY_PRICE_WITH_TAX == 'true') && ($tax > 0) ) {
return $price + zen_calculate_tax($price, $tax);
} else {
return $price;
}
}
to this:
Code:
function zen_add_tax($price, $tax) {
global $currencies;
if ($_SESSION['customer_whole'] == 1) {
return $price;
}
if ((DISPLAY_PRICE_WITH_TAX == 'true') && ($tax > 0)) {
return $price + zen_calculate_tax($price, $tax);
} else {
return $price;
}
}
It works and displays prices including taxes to customers and without taxes to wholesalers.
The problem is that I want taxes to be applied to everybody at checkout. In this case the grand total is applied only to customers, not to wholesalers as well.
How can I do to make the grand total including taxes for everybody? Thank you.
Re: Bug: price manager adds Tax to the promotional price! Help needed...
In this case, need to clear the SESSION variable in the includes/modules/pages/YOUR_PAGE/header_php.php file on the page where you want normal taxing to occur. But I suggest setting a different variable or the value tosomethingelseand to evaluate where one could end up next. In the follow on location(s), check for that variable set. As it is, and revert it to the value of '1' so that the views elsewhere are consistent upon "departure".from that first page.
Re: Bug: price manager adds Tax to the promotional price! Help needed...
Thank you, could you please tell me which page (I assume checkout_payment folder) and which code should i put?
The original code is this, what changes should I make?
Code:
<?php
/**
* checkout_payment header_php.php
*
* @package page
* @copyright Copyright 2003-2007 Zen Cart Development Team
* @copyright Portions Copyright 2003 osCommerce
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
* @version $Id: header_php.php 16397 2010-05-26 11:21:22Z drbyte $
*/
// This should be first line of the script:
$zco_notifier->notify('NOTIFY_HEADER_START_CHECKOUT_PAYMENT');
// if there is nothing in the customers cart, redirect them to the shopping cart page
if ($_SESSION['cart']->count_contents() <= 0) {
zen_redirect(zen_href_link(FILENAME_TIME_OUT));
}
// if the customer is not logged on, redirect them to the login page
if (!$_SESSION['customer_id']) {
$_SESSION['navigation']->set_snapshot();
zen_redirect(zen_href_link(FILENAME_LOGIN, '', 'SSL'));
} else {
// validate customer
if (zen_get_customer_validate_session($_SESSION['customer_id']) == false) {
$_SESSION['navigation']->set_snapshot();
zen_redirect(zen_href_link(FILENAME_LOGIN, '', 'SSL'));
}
}
// if no shipping method has been selected, redirect the customer to the shipping method selection page
if (!$_SESSION['shipping']) {
zen_redirect(zen_href_link(FILENAME_CHECKOUT_SHIPPING, '', 'SSL'));
}
if (isset($_SESSION['shipping']['id']) && $_SESSION['shipping']['id'] == 'free_free' && defined('MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_OVER') && $_SESSION['cart']->show_total() < MODULE_ORDER_TOTAL_SHIPPING_FREE_SHIPPING_OVER) {
zen_redirect(zen_href_link(FILENAME_CHECKOUT_SHIPPING, '', 'SSL'));
}
// avoid hack attempts during the checkout procedure by checking the internal cartID
if (isset($_SESSION['cart']->cartID) && $_SESSION['cartID']) {
if ($_SESSION['cart']->cartID != $_SESSION['cartID']) {
zen_redirect(zen_href_link(FILENAME_CHECKOUT_SHIPPING, '', 'SSL'));
}
}
// Stock Check
if ( (STOCK_CHECK == 'true') && (STOCK_ALLOW_CHECKOUT != 'true') ) {
$products = $_SESSION['cart']->get_products();
for ($i=0, $n=sizeof($products); $i<$n; $i++) {
if (zen_check_stock($products[$i]['id'], $products[$i]['quantity'])) {
zen_redirect(zen_href_link(FILENAME_SHOPPING_CART));
break;
}
}
}
// get coupon code
if ($_SESSION['cc_id']) {
$discount_coupon_query = "SELECT coupon_code
FROM " . TABLE_COUPONS . "
WHERE coupon_id = :couponID";
$discount_coupon_query = $db->bindVars($discount_coupon_query, ':couponID', $_SESSION['cc_id'], 'integer');
$discount_coupon = $db->Execute($discount_coupon_query);
}
// if no billing destination address was selected, use the customers own address as default
if (!$_SESSION['billto']) {
$_SESSION['billto'] = $_SESSION['customer_default_address_id'];
} else {
// verify the selected billing address
$check_address_query = "SELECT count(*) AS total FROM " . TABLE_ADDRESS_BOOK . "
WHERE customers_id = :customersID
AND address_book_id = :addressBookID";
$check_address_query = $db->bindVars($check_address_query, ':customersID', $_SESSION['customer_id'], 'integer');
$check_address_query = $db->bindVars($check_address_query, ':addressBookID', $_SESSION['billto'], 'integer');
$check_address = $db->Execute($check_address_query);
if ($check_address->fields['total'] != '1') {
$_SESSION['billto'] = $_SESSION['customer_default_address_id'];
$_SESSION['payment'] = '';
}
}
require(DIR_WS_CLASSES . 'order.php');
$order = new order;
// Load the selected shipping module(needed to calculate tax correctly)
require(DIR_WS_CLASSES . 'shipping.php');
$shipping_modules = new shipping($_SESSION['shipping']);
require(DIR_WS_CLASSES . 'order_total.php');
$order_total_modules = new order_total;
$order_total_modules->collect_posts();
$order_total_modules->pre_confirmation_check();
// $_SESSION['comments'] = '';
$comments = $_SESSION['comments'];
$total_weight = $_SESSION['cart']->show_weight();
$total_count = $_SESSION['cart']->count_contents();
// load all enabled payment modules
require(DIR_WS_CLASSES . 'payment.php');
$payment_modules = new payment;
$flagOnSubmit = sizeof($payment_modules->selection());
require(DIR_WS_MODULES . zen_get_module_directory('require_languages.php'));
if (isset($_GET['payment_error']) && is_object(${$_GET['payment_error']}) && ($error = ${$_GET['payment_error']}->get_error())) {
$messageStack->add('checkout_payment', $error['error'], 'error');
}
$breadcrumb->add(NAVBAR_TITLE_1, zen_href_link(FILENAME_CHECKOUT_SHIPPING, '', 'SSL'));
$breadcrumb->add(NAVBAR_TITLE_2);
// This should be last line of the script:
$zco_notifier->notify('NOTIFY_HEADER_END_CHECKOUT_PAYMENT');
?>
Re: Bug: price manager adds Tax to the promotional price! Help needed...
Sorry for the delay.
So the truly zen way would be to write an observer to listen to: NOTIFY_HEADER_START_CHECKOUT_PAYMENT
In which the software would be something like:
Will be creating two files.
The first to go into includes/auto_loaders
Suggest giving it a name that has meaning to the task. Something like config.whole_sale_taxes.php
Code:
<?php
/**
* Autoloader array for products with attributes stock (SBA) functionality. Makes sure that products with attributes stock is instantiated at the
* right point of the Zen Cart initsystem.
*
* @package whole_sale_taxes.php
* @author mc12345678
* @copyright Copyright 2008-2015 mc12345678
* @copyright Copyright 2003-2007 Zen Cart Development Team
* @copyright Portions Copyright 2003 osCommerce
* @link http://www.zen-cart.com/
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
* @version $Id: config.whole_sale_taxes.php xxxx 2015-06-15
*
* Modify the tax display of wholesale taxes
*/
$autoLoadConfig[0][] = array(
'autoType' => 'class',
'loadFile' => 'observers/class.whole_sale_taxes.php'
);
$autoLoadConfig[199][] = array(
'autoType' => 'classInstantiate',
'className' => 'whole_sale_taxes',
'objectName' => 'whole_sale_taxes_observe'
);
?>
The second is the class file that functions as the observer, listening and waiting for the primary code to take some form of action to which this will take action.
Based on the above information the filename for this second file would be class.whole_sale_taxes.php and stored in the directory: includes/classes/observers
Code:
<?php
/**
* Description of class.whole_sale_taxes: This class is used to support tax information related to the wholesale module. This way reduces the modifications of the includes/modules/pages/checkout_payment/header_php.php and other files reached from that page to nearly nothing.
*
* @author mc12345678
*
*/
class whole_sale_taxes extends base {
/*
* This is the observer for the includes/modules/pages/checkout_payment/header_php.php file to support taxing everyone equally when the order is being processed at the end of the purchase.
*/
function whole_sale_taxes() {
global $zco_notifier;
$zco_notifier->attach($this, array('NOTIFY_HEADER_START_CHECKOUT_PAYMENT', 'NOTIFY_ORDER_PROCESSING_ATTRIBUTES_BEGIN', 'NOTIFY_HEADER_START_CHECKOUT_SHIPPING', 'NOTIFY_HEADER_START_CHECKOUT_SUCCESS', 'NOTIFY_HEADER_START_CHECKOUT_SHIPPING_ADDRESS', 'NOTIFY_HEADER_START_CHECKOUT_PROCESS', 'NOTIFY_HEADER_START_CHECKOUT_PAYMENT_ADDRESS', 'NOTIFY_HEADER_START_CHECKOUT_CONFIRMATION', 'NOTIFY_HEADER_START_SHOPPING_CART', 'NOTIFY_HEADER_START_LOGIN'));
}
/*
* Generic function that is activated when any notifier identified in the observer is called but is not found in one of the updated methods of calling an observer (ZC 1.5.3+) is encountered as a notifier.
*/
function update(&$callingClass, $notifier, $paramsArray) {
global $db;
// remove the session variable that removes tax from the calculations.
if ($notifier == 'NOTIFY_HEADER_START_CHECKOUT_PAYMENT'){
if ($_SESSION['customer_whole']=='1') {
unset($_SESSION['customer_whole']);
$_SESSION['customer_whole_reset']='1';
}
}
// restore the tax "discount" so that the customer continues to see the untaxed price until returning to the above page(s).
if ($notifier == 'NOTIFY_ORDER_PROCESSING_ATTRIBUTES_BEGIN' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_SHIPPING' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_SUCCESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_SHIPPING_ADDRESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_PROCESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_PAYMENT_ADDRESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_CONFIRMATION' || $notifier == 'NOTIFY_HEADER_START_SHOPPING_CART' || $notifier == 'NOTIFY_HEADER_START_LOGIN') {
if ($_SESSION['customer_whole_reset']=='1') {
unset($_SESSION['customer_whole_reset']);
$_SESSION['customer_whole']='1'
}
}
} //end update function - mc12345678
} //end class - mc12345678
?>
I believe I've overdone it a little in the second set of checks (to restore the condition back to where the customer is recognized as a wholesale customer) and may have missed an appropriate page, but, perhaps you get the jest.
So often I forget to put the additional notifiers to which to listen up at the declaration function... Get so carried away with the actions to be taken that I forget to tell the code to listen for the notifier. :)
Re: Bug: price manager adds Tax to the promotional price! Help needed...
Thank you for your help. I tried creating those two files and uploading them.
Those two files create an error that cause zencart to show a blank page instead of the store homepage.
Dreamweaver highlights a syntax error in the row coloured in red:
Code:
// restore the tax "discount" so that the customer continues to see the untaxed price until returning to the above page(s).
if ($notifier == 'NOTIFY_ORDER_PROCESSING_ATTRIBUTES_BEGIN' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_SHIPPING' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_SUCCESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_SHIPPING_ADDRESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_PROCESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_PAYMENT_ADDRESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_CONFIRMATION' || $notifier == 'NOTIFY_HEADER_START_SHOPPING_CART' || $notifier == 'NOTIFY_HEADER_START_LOGIN') { if ($_SESSION['customer_whole_reset']=='1') { unset($_SESSION['customer_whole_reset']);
$_SESSION['customer_whole']='1'
}
Do you have any suggestion to fix it?
Thank you.
Re: Bug: price manager adds Tax to the promotional price! Help needed...
Quote:
Originally Posted by
ilmarchez
Thank you for your help. I tried creating those two files and uploading them.
Those two files create an error that cause zencart to show a blank page instead of the store homepage.
Dreamweaver highlights a syntax error in the row coloured in red:
Code:
// restore the tax "discount" so that the customer continues to see the untaxed price until returning to the above page(s).
if ($notifier == 'NOTIFY_ORDER_PROCESSING_ATTRIBUTES_BEGIN' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_SHIPPING' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_SUCCESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_SHIPPING_ADDRESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_PROCESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_PAYMENT_ADDRESS' || $notifier == 'NOTIFY_HEADER_START_CHECKOUT_CONFIRMATION' || $notifier == 'NOTIFY_HEADER_START_SHOPPING_CART' || $notifier == 'NOTIFY_HEADER_START_LOGIN') { if ($_SESSION['customer_whole_reset']=='1') { unset($_SESSION['customer_whole_reset']);
$_SESSION['customer_whole']='1'
}
Do you have any suggestion to fix it?
Thank you.
Yeah, change:
Code:
$_SESSION['customer_whole']='1'
To:
Code:
$_SESSION['customer_whole']='1';