Zen Cart Logo
Forums / All Other Contributions/Addons / Dynamic Price Updater

Dynamic Price Updater

Views: 342,273

Results 621 to 640 of 1,701
22 Mar 2010, 5:21 PM
#621
florianfischer avatar

florianfischer

New Zenner

Join Date:
Mar 2010
Posts:
2
Plugin Contributions:
0

Dynamic Price Updater

Hi Dan,

thank you for your answers and time you have to spend.

Take care
Flo

22 Apr 2010, 7:17 AM
#622
goldbuckle avatar

goldbuckle

Zen Follower

Join Date:
Dec 2006
Location:
near Atlanta Georgia
Posts:
219
Plugin Contributions:
0

Re: Dynamic Price Updater

I like this add on, but I have a small issue I can't seem to work out. I sell printing and want to set up my products with attribute pricing so my customers can calculate a price for any quantity instantly.

The way I have to price my products I need to us an attribute with a price per copy (ex. $0.01 for #20 white bond) and also use a one time charge (ex. $20.00) for setup costs of the print run. I put a test product on my site but it only shows the price per copy for Your Price: and doesn't add in the one time charge. It shows the total correctly in the shopping cart just not on the Your Price amount on the product page.

http://discountprintingservice.com/index.php?main_page=product_info&cPath=69&products_id=19812

Can your add on be configured so it will show the total price???

Thanks,
GoldBuckle

22 Apr 2010, 8:59 AM
#623
jstnice avatar

jstnice

New Zenner

Join Date:
Apr 2010
Posts:
2
Plugin Contributions:
0

Re: Dynamic Price Updater

Chrome:

Hi

I don't know if this module will be of any use to anyone but I've been asked to include it a couple of times so thought I'd release it into the wild to see if anyone can make use of it... Here's what it does:

When you have a product with attributes that alter the price this module will update the price displayed on the page instantly... This gives customers an at-a-glance price total as opposed to having to work it out themselves

The updater should (in theory) work with any amount of attributes

There is a readme included in the ZIP but installation is literally to just upload the file... It overwrites nothing, has no database hooks and is completely autonomous... if it breaks just delete the file

Currently it only works with attributes that are SELECTs... If it works for people I will update it to handle the radio boxes and checkboxes

The file can be found at http://chrome.me.uk/PriceUpdater.zip

A working version can be seen at http://www.studio5.uk.com/index.php?main_page=product_info&cPath=2&products_id=3

Let me know if it does/doesn't work or if anyone wants anything added or changed

Dan

:clap:I think it is nice!

22 Apr 2010, 4:12 PM
#624
goldbuckle avatar

goldbuckle

Zen Follower

Join Date:
Dec 2006
Location:
near Atlanta Georgia
Posts:
219
Plugin Contributions:
0

Re: Dynamic Price Updater

Thanks for the reply jstnice, but my question still isn't answered. In your attribute setting you have boxes to enter pricing per attribute:
Prices & Weights
Price---------Weight--------Order----------One Time
+.02-------------0-------------1---------------$25.00

When I test it it is only calculating the Price (+.02) and is not adding in the one time charge of $25.00. It does however add up in the shopping cart, it just doesn't show up on the product page for Your Price

For example, (base on the above example) if someone orders 1000 flyers it should multiply 1000 by the Price of +.02 (which would be $20.00) then add the one time charge of $25.00 for a total of $45.00.

On my test product it is only multiplying the price +0.02 by 1000 and displaying that number without adding in the one time charge of $25.00.

Can anyone tell me how to fix this???

:frusty:

30 Apr 2010, 9:14 PM
#625
goldbuckle avatar

goldbuckle

Zen Follower

Join Date:
Dec 2006
Location:
near Atlanta Georgia
Posts:
219
Plugin Contributions:
0

Re: Dynamic Price Updater

Anyone got any ideas on this one???

9 May 2010, 6:50 PM
#626
djw925 avatar

djw925

New Zenner

Join Date:
Nov 2009
Location:
worcester
Posts:
3
Plugin Contributions:
0

Re: Dynamic Price Updater

Hi

Can anyone shed any light on this query!!

I have the Dynamic Price Updater installed on my website and:

I have been adding extra prices to certain attributes of my products recently and have now noticed the sum of the attributes (at product level) are different to the data that is inputted into Zen.

However, when you add the product to cart, the price reverts back to the correct price! You can also briefly see the correct price if you refresh the page at product level, but it will then change, and settle incorrectly.

I have gone through numerous settings on zen to track down where the error is coming from and it seems that the problem occurs when I change the individual products' 'Tax Class' from 'none' to 'Taxable Goods'. (which I have set at 17.5%)

If you have the time to take a quick look at the site:

http://www.prestigeringcompany.com/i...roducts_id=377

and suggest any solutions to this I would be most grateful.

I hope that makes sense.

cheers

Darrel

11 May 2010, 8:23 PM
#627
djw925 avatar

djw925

New Zenner

Join Date:
Nov 2009
Location:
worcester
Posts:
3
Plugin Contributions:
0

Re: Dynamic Price Updater

Sorry, to add:

I am currently using version 1.3.8

The price on the product page is always higher (1%) than it should be. If you refresh the page, you can see the CORRECT price very briefly and then it settles INCORRECTLY.

However, when you add the product to cart, the price reverts back to the CORRECT price that has been set for that particular product!!

I have viewed the 'pricing round up' thread issues, and it doesn't seem to be this as it is only the Dynamic Price Updater that gets the incorrect total.

Any suggestions would be very appreciated.

Thanks

Darrel

14 May 2010, 2:36 PM
#628
fcaceres71 avatar

fcaceres71

New Zenner

Join Date:
May 2009
Location:
USA
Posts:
8
Plugin Contributions:
0

Re: Dynamic Price Updater

In my store I have a large amount of products that have no attributes, and when I use the DPUv2 the products that I have specials and no attributes get updated with the Special Price and when the product is Sold Out it shows as "Your Price: 0.00". The product that I'm testing has 3 attributes. The first one is "Add Canopy" and it is a check that adds $91.00. The second one is the finish options with radio buttons. They don't add any amount to the price, and the last attribute is purely a test called Other Option with a "Just Add Me" value and adds the amount of $35.00 to the price. Well, in that order, the canopy Updates the price with the $91.00, but the Just Add Me does not Update the price with its $35.00. If I shuffle the order of the attributes to Add Canopy (first), Just Add Me (second), and the Finish at the end, then it works and both Attributes get to Update the Price.

Using the original DPU, there are no problems with the rest of the products that don't have attributes. The test product with the attributes works exactly the same way that it does with DPUv2 but in IE it shows the Done (with errors) symbol on the lower left corner of the browser and when double clicking the error we get:

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Timestamp: Fri, 14 May 2010 13:13:58 UTC

Message: Object required
Line: 158
Char: 4
Code: 0
URI: http://f i s h p e t l o v e.com/index.php?main_page=product_info&cPath=11&products_id=14580

Message: Object required
Line: 158
Char: 4
Code: 0
URI: http://f i s h p e t l o v e.com/index.php?main_page=product_info&cPath=11&products_id=14580

The error only shows in some IE in some computers, I have seen the IE in two different setups in different locations. I talk with my hosting and they had the same version of IE I have (version: 8.0.6001.18702 running Windows XP) and they didn't see the error. Firefox does not show the error. I setted up IE to not show errors, and it is still showing.:cry::frusty::Flush:

My jscript_updater.php looks like:

<?php
// Small module to dynamically update main price when the product has price altering attributes

// (c) D Parry (Chrome) 2007 ([email protected])
// This module is free to distribute and use as long as the above copyright message is left in tact

// Alterations are permitted but please let me know of any changes you make, specifically where incompatibility is concerned

// some contstant declarations
define('UPDATER_PREFIX_TEXT', 'Price: ');
define('UPDATER_SB_TITLE', 'Price Breakdown'); // the heading that shows in the Updater sidebox
?>
<script language="javascript" type="text/javascript">
// <![CDATA[

var objPrice, origPrice;
var defaultCurrencyLeft, defaultCurrencyRight;
defaultCurrencyLeft = defaultCurrencyRight = '';
var quantity = false; // do not alter this
var showQuantity = false; // show the quantity the customer has requested in the main price header
var showQuantitySB = false; // show the quantity the customer has requested in the sidebox
var prArr = nameArr = new Array(); // holds an array of prices to be adjusted (for multiple price adjustments)
var _oflag = false; // do not alter this

var seeker = new RegExp(/\(\s*([+-]?)([^0-9]*)([0-9,]+\.[0-9]+)([^0-9)]*)\s*\)/);

// Updater sidebox settings
var _sidebox = false; // set this to: false - don't use or the ID of the sidebox you want the display to insert above (must be exact)
var objSB = false; // this holds the sidebox object

// Second price setting
// the following settings allow a second price to be displayed... if a page is very long this allows you to add another price display
// thanks to Ryk on the Zen Cart forums for the idea and pointing out the issue
var _secondPrice = 'false'; // set this to either false for disabled or supply the ID of an element for the price to appear BEFORE... for example, cartAdd
var _SPDisplay = 'update'; // governs the behaviour of the second... 'always' permanently displays and 'update' shows the second price only when an attribute is selected
var objSP = false; // please don't adjust this

// debug settings
var _debug = false; // set to false to disable debug output
var _db = '';
var _dbdiv = false;

function init() { // discover the selects that are required to adjust the main price
	var centre = document.getElementById('productGeneral');
	var objSel = centre.getElementsByTagName('SELECT');
	var objInp = centre.getElementsByTagName('INPUT');
	var db = '';
	var _flag = false; // flag to decide if a load of attribute information is needed

	if (!_oflag)	{ // get the base price and the quantity box (if it exists)
		// firstly find out if debug messages should be shown
		if (_debug === true) { // build the div that will hold debug messages
			createdb();
		}

		if (_secondPrice !== false && _SPDisplay == 'always') {
			regdb('SP Onload', 'Type: ' + _SPDisplay);
			updSP();
		}

		// quantity box
		var qtemp = document.getElementById('cartAdd');
		if (qtemp) { // got the containing div... go for the quantity!
			var itemp = qtemp.getElementsByTagName('INPUT');
			if (itemp) { // make sure some inputs are available to scan
				for (var i=0; itemp[i]; i++) {
					if (itemp[i].name == 'cart_quantity') { // we have the input we need
						quantity = itemp[i].value;
						regdb('Onload quantity', 'Cart add INPUT discovered (' + quantity + ')');
						itemp[i].onkeyup = function () { adjQuan(this); }
					}
				}
			}
		}
		// if quantity is still false we'll assign it a value of 1
		if (quantity === false)	quantity = 1;

		if (!(objPrice = document.getElementById('productPrices').getElementsByTagName('SPAN')[1])) {
			objPrice = document.getElementById('productPrices');
		} else {
			regdb('Onload sale', 'Looks like an item on sale');
		}

		origPrice = Number(objPrice.innerHTML.match(/([0-9,.]+)/g)[0].replace(/,/g, ''));
		var origHTML = objPrice.innerHTML;
		var db = '';
		if (!origPrice) {
			db = 'Initial phase failure';
			if (objPrice) {
				db += ' - H2 found';
				var temp = objPrice.getElementsByTagName('SPAN');
				for (var i=0; temp[i]; i++) {
					if (temp[i].className = 'productSpecialPrice') {
						origPrice = temp[i].innerHTML.match(/([0-9,.]+)/g)[0].replace(/,/g, '');
						db += ' - price in SPAN';
						origHTML = temp[i].innerHTML;
						if (!origPrice)	return;
					}
				}
			} else {
				db += ' - price not found!';
				return;
			}
		} else {
			db = 'Price found: ' + origPrice;
		}
		regdb('Onload base price', db);

		// try and find the default currency symbols
		var temp = origHTML.match(/s*([^0-9 ]*)([0-9.,]+)(.*)/);
		defaultCurrencyLeft = temp[1];
		db = 'Left: ' + defaultCurrencyLeft;
		defaultCurrencyRight = temp[3];
		db += ' - Right: ' + defaultCurrencyRight;
		regdb('Onload default currency locator', db);
	}

	for (var i=0; objSel[i]; i++) {
		var _this = objSel[i];

		objSel[i].onchange = function () { updatePrice(this); }
		db = 'Name - ' + objSel[i].name + ' : ID - ' + objSel[i].id;

		// scan the attributes to find out if any adjustments are needed
		var matches = objSel[i][objSel[i].selectedIndex].text.match(seeker);

		if (matches) { // yep
			db += ' - Adjusted!';
			prArr[objSel[i].id] = new Array();
			prArr[objSel[i].id]['p'] = Number(matches[3].replace(/,/, '')); // push the value onto the stack
			prArr[objSel[i].id]['n'] = objSel[i][objSel[i].selectedIndex].text.replace(seeker, '');
			prArr[objSel[i].id]['m'] = matches[1]; // mode indicator
			prArr[objSel[i].id]['l'] = matches[2]; // left side currency indeicator
			prArr[objSel[i].id]['r'] = matches[4]; // the right side currency indicator
			_flag = true;
		}

		regdb ('Onload SELECT', db);
	}

	for (var i=0; objInp[i]; i++) {
		if (objInp[i].type == 'radio' || objInp[i].type == 'checkbox') { // make sure we're dealing with radio boxes
			db = 'Name - ' + objInp[i].name + ' : ID - ' + objInp[i].id;
			matches = objInp[i].nextSibling.innerHTML.match(seeker);
			if (matches) {
				db += ' : Adjusted!';
				objInp[i].onclick = function () { updateR(this); }
				if (objInp[i].checked)	updateR(objInp[i]);
			}
		}
		regdb('Onload RAD/CH', db);
	}

	if (_flag  && !_oflag)	{
		updatePriceNow();
	}

	if (_oflag === true)	regdb('Onload', '--- End of loading procedures ---');
	_oflag = true;
}

function updSP() {
	// adjust the second price display; create the div if necessary
	var flag = false; // error tracking flag

	if (_secondPrice !== false) { // second price is active
		var centre = document.getElementById('productGeneral');
		var temp = document.getElementById('productPrices');
		var itemp = document.getElementById(_secondPrice);

		if (objSP === false) { // create the second price object
			if (!temp || !itemp)	flag = true;

			if (!flag) {
				objSP = temp.cloneNode(true);
				objSP.id = temp.id + 'Second';
				regdb('updSP', 'Price node cloned!');

				if (!itemp.parentNode.insertBefore(objSP, itemp.nextSibling)) {
					regdb('updSP', 'Unable to insert node at point ' + _secondPrice);
				} else {
					regdb('updSP', 'Node inserted successfully');
				}
			} else {
				regdb('updSP', 'Unable to clone price node!');
			}
		}

		regdb('updSP', 'Duplicating price, by jove!');
		objSP.innerHTML = temp.innerHTML;
	} else { // second price inactive
		regdb('updSP', 'Cancelled');
	}
}

function adjQuan(objInp) {
	// adjust the global cart quantity for multiplication
	var newVal = Number(objInp.value.match(/[0-9]+/g));

	quantity = newVal;
	regdb('Quantity change', newVal);
	updatePriceNow();
	if (_sidebox !== false && objSB === false)	createSB();
	if (objSB !== false)	updateSB(); // update the sidebox
}

function updateR(objInp) {
	var matches = objInp.nextSibling.innerHTML.match(seeker);
	var priceAdj, totalAdj = 0;
	var flag = false;
	var db = '';

	if (matches) { // make sure this attribute is price-adjust-worthy
		db += '*Adj* - ';
		priceAdj = Number(matches[3].replace(/,/g, '')); // Number(matches[0].match(/[0-9.]+/)[0]);
	} else {
		db += '*No adj* - ';
		priceAdj = 0;
	}

	if (objInp.type == 'radio') {
		// the radio type input can be inserted into the array using its name as a reference as radio boxes are mutually
		// exclusive in their group
		db += 'Radio - Name: ' + objInp.name + ' - ';
		prArr[objInp.name] = new Array();
		prArr[objInp.name]['p'] = priceAdj; // push the price adjustment into the array referenced by the ID of the calling select
		prArr[objInp.name]['n'] = objInp.nextSibling.innerHTML.replace(seeker, '');
		prArr[objInp.name]['m'] = matches[1];
		prArr[objInp.name]['l'] = matches[2]; // left side currency indeicator
		prArr[objInp.name]['r'] = matches[4]; // the right side currency indicator
		db += 'Price adjust: ' + priceAdj + ' - Mode: ' + matches[1];
	} else {
		// checkboxes are always autonomous so can have multiple selections from a group so use the ID as before
		if (objInp.checked) {
			db += 'Checkbox - ID: ' + objInp.id + ' - ';
			prArr[objInp.id] = new Array();
			prArr[objInp.id]['p'] = priceAdj; // push the price adjustment into the array referenced by the ID of the calling select
			prArr[objInp.id]['n'] = objInp.nextSibling.innerHTML.replace(seeker, ''); // attribute name, price removed
			prArr[objInp.id]['m'] = matches[1]; // the mode (+, - or base) of the attribute
			prArr[objInp.id]['l'] = matches[2]; // left side currency indeicator
			prArr[objInp.id]['r'] = matches[4]; // the right side currency indicator
			db += 'Price adjust: ' + priceAdj + ' - Mode: ' + matches[1];
		} else {
			prArr[objInp.id] = null;
			db = 'Checkbox ID ' + objInp.id + ' is now NULL';
		}
	}

	regdb('updateR', db);
	updatePriceNow();
}

function updatePrice(objSel) { // update the main price from the value extracted by the regex
	var matches = objSel[objSel.selectedIndex].text.match(seeker);
	var priceAdj, totalAdj = 0;
	var db = '';

	if (matches) { // make sure this attribute is price-adjust-worthy
		db = '*Adj* - ';
		priceAdj = Number(matches[3].replace(/,/g, ''));
	} else {
		db = '*No adj* - ';
		priceAdj = 0;
	}

	if (matches)	{
		prArr[objSel.id] = new Array();
		prArr[objSel.id]['p'] = priceAdj; // push the price adjustment into the array referenced by the ID of the calling select
		prArr[objSel.id]['n'] = objSel[objSel.selectedIndex].text.replace(seeker, '');
		prArr[objSel.id]['m'] = matches[1];
		prArr[objSel.id]['l'] = matches[2]; // left side currency indeicator
		prArr[objSel.id]['r'] = matches[4]; // the right side currency indicator
		db += 'ID: ' + objSel.id + ' - Price adjust: ' + priceAdj + ' - Mode: ' + matches[1];
	} else {
		prArr[objSel.id] = null;
		db = 'SELECT ID ' + objSel.id + ' is now NULL';
	}

	regdb('updatePrice', db);
	updatePriceNow();
}

function updatePriceNow() { // update the price display
	var totalAdj = 0;
	var db = '';
	var l = defaultCurrencyLeft;
	var r = defaultCurrencyRight;

	for (var i in prArr) {
		if (prArr[i] == '') {
			l = (prArr[i]['l'] == '' || typeof(prArr[i]['l']) == 'undefined' ? defaultCurrencyLeft : prArr[i]['l']);
			r = (prArr[i]['r'] == '' ? defaultCurrencyRight : prArr[i]['r']);
			db = 'Item: ' + prArr[i]['n'] + ' - ';
			switch (true) { // adjust the price according to its given mode
				case prArr[i]['m'] == '+': // add the attribute price to the base price
					db += 'Mode: Add';
					db += ' - totalAdj: ' + totalAdj + ' - Adding ' + prArr[i]['p'];
					totalAdj += prArr[i]['p'];
					break;
				case prArr[i]['m'] == '-': // subtract the attribute price from the base
					db += 'Mode: Subtract';
					db += ' - totalAdj: ' + totalAdj + ' - Subtracting ' + prArr[i]['p'];
					totalAdj -= prArr[i]['p'];
					break;
				case prArr[i]['m'] == '': // this means the attribute actually replaces the base price
					db += 'Mode: Base';
					db += ' - Altering base to ' + prArr[i]['p'];
					origPrice = prArr[i]['p'];
					break;
			}
			regdb('updatePriceNow', db);
		}
	}

	var newPrice = ((origPrice + totalAdj) * quantity).toFixed(2);
	document.getElementById('productPrices').innerHTML = '<?php echo UPDATER_PREFIX_TEXT; ?>' + l + addCommas(newPrice) + r + (showQuantity ? ' (' + quantity + ')' : '');
	if (_sidebox !== false && objSB === false)	createSB();
	if (objSB !== false)	updateSB(); // update the sidebox
	updSP();
}

function createSB() { // create the sidebox for the attributes info display
	if (_sidebox !== false) {
		var temp = document.getElementById(_sidebox); // get a handle to the sidebox to insertBefore
		if (temp) {
			objSB = document.createElement('DIV'); // create the sidebox wrapper
			objSB.id = 'updaterSB';
			objSB.className = 'leftBoxContainer'; // set the CSS reference
			// create the heading bit
			var tempH = document.createElement('H3');
			tempH.id = 'updateSBHeading';
			tempH.className = 'leftBoxHeading';
			tempH.innerHTML = '<?php echo UPDATER_SB_TITLE; ?>';
			objSB.appendChild(tempH);
			// create the content div
			var tempC = document.createElement('DIV');
			tempC.id = 'updaterSBContent';
			tempC.className = 'sideBoxContent';
			tempC.innerHTML = 'If you can read this Chrome has broken something';
			objSB.appendChild(tempC);

			temp.parentNode.insertBefore(objSB, temp);
			regdb('createSB', 'Sidebox created!');
		} else {
			regdb('createSB', 'Sidebox could not be created!');
		}
	}
}

function updateSB() { // update the contents of the sidebox with the updated info from the attributes selector
	var newText = hText = '';
	var l = defaultCurrencyLeft;
	var r = defaultCurrencyRight;
	var totalAdj = origPrice;

	for (var i in prArr) {
		if (prArr[i] == '') {
			l = (prArr[i]['l'] == '' || typeof(prArr[i]['l']) == 'undefined' ? defaultCurrencyLeft : prArr[i]['l']);
			r = (prArr[i]['r'] == '' ? defaultCurrencyRight : prArr[i]['r']);

			if (prArr[i]['m'] !== null && prArr[i]['m'] != '')	{
				if (prArr[i]['m'] == '-')	newText += '<span style="color: red;">';
				newText += prArr[i]['n'] + (prArr[i]['p'] != 0 ? ' - ' + (showQuantitySB ? quantity + 'x ' : '') + prArr[i]['l'] + prArr[i]['p'].toFixed(2) + prArr[i]['r']: '') + '<br/>';
				if (prArr[i]['m'] == '-')	newText += '<\/span>';
				switch (true) { // adjust the price according to its given mode
					case prArr[i]['m'] == '+': // add the attribute price to the base price
						totalAdj += prArr[i]['p'];
						break;
					case prArr[i]['m'] == '-': // subtract the attribute price from the base
						totalAdj -= prArr[i]['p'];
						break;
					case prArr[i]['m'] == '': // this means the attribute actually replaces the base price
						origPrice = prArr[i]['p'];
						break;
				}
			}
		}
	}

	hText += 'Product price - ' + (showQuantitySB ? quantity + 'x ' : '') + l + addCommas(origPrice.toFixed(2)) + r + '<br/>';
	newText += '<hr />Total: ' + l + addCommas((totalAdj * quantity).toFixed(2)) + r;

	// I know innerHTML is cheating but I careth not :)
	objSB.getElementsByTagName('DIV')[0].innerHTML = hText + newText;
}

function addCommas(nStr)
{ // this function can be found at http://www.mredkj.com/javascript/numberFormat.html#addcommas
	nStr += '';
	var x = nStr.split('.');
	var x1 = x[0];
	var x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}

function createdb () {
	var centre = document.getElementById('productGeneral');

	if (_dbdiv === false) {
		_dbdiv = document.createElement('DIV');
		_dbdiv.style.border = '2px dashed #666';
		_dbdiv.style.padding = '0.1em';
		centre.appendChild(_dbdiv)
	}
	_dbdiv.innerHTML = '<div style="cursor: pointer; width: 100%; text-align: center; margin-bottom: 5px; background-color: #aaa; padding: 1px; font-size: 110%; font-weight: bold;" onclick="createdb();">Debug messages<\/div>';
}

function regdb(strTitle, strText) { // simple routine to format and output the debug messages
	if (_debug === true) { // make sure debug messages should be displayed
		_dbdiv.innerHTML += '<div style="margin: 2px 0; background-color: #ddd; border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;"><span style="font-weight: bold;">' + strTitle + ':<\/span> ' + strText + '<\/div>';
	}
}

// the following statements should allow multiple onload handlers to be applied
// I know this type of event registration is technically deprecated but I decided to use it because I haven't before
// There shouldn't be any fallout from the downsides of this method as only a single function is registered (and in the bubbling phase of each model)
// For backwards compatibility I've included the traditional DOM registration method
try { // the IE event registration model
	window.attachEvent('onload', init);
} catch (e) { // W3C event registration model
	window.addEventListener('load', init, false);
} finally {
	window.onload = init;
}

// ]]></script>

Help Please.

Fred

18 May 2010, 10:53 AM
#629
chrome avatar

chrome

Zen Follower

Join Date:
Jul 2005
Location:
Wales, UK
Posts:
392
Plugin Contributions:
0

Re: Dynamic Price Updater

Hi all

Sorry for taking ages to reply... I've been away from my machine for some time and I'm just now getting caught up with everything

The tax problem I think I have an idea about now so I'm going to be looking into it as soon as I can

Fred, have you tried V2 of the Updater to see what that makes of your attributes? I know V2 has some issues currently but these seem to largely revolve around the tax class

Let me know and I will also check out your site

Cheers

Dan

19 May 2010, 3:01 AM
#630
fcaceres71 avatar

fcaceres71

New Zenner

Join Date:
May 2009
Location:
USA
Posts:
8
Plugin Contributions:
0

Re: Dynamic Price Updater

Hi Dan, Check out the test product I set up with some attributes:

http://f i s h p e t l o v e . c o m /test

Just put the letters together and you will be there
I tried V2 also, but V2 had more problems. v1 gives the following error in the little triangle (Done but with errors) only shows in Internet explorer:

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Timestamp: Wed, 19 May 2010 02:59:25 UTC

Message: Object required
Line: 158
Char: 4
Code: 0
URI: http://f i s h p e t l o v e . c o m /test

Message: Object required
Line: 158
Char: 4
Code: 0
URI: http://f i s h p e t l o v e . c o m /test

Thanks

Fred.

19 May 2010, 6:17 AM
#631
fcaceres71 avatar

fcaceres71

New Zenner

Join Date:
May 2009
Location:
USA
Posts:
8
Plugin Contributions:
0

Re: Dynamic Price Updater

After looking at the error couple of times I figured out how to fix the problem, hopefully my fix is not going to kick me back :lamo: We will find out in the next couple of weeks, but here it goes:

	for (var i=0; objInp[i]; i++) {
		if (objInp[i].type == 'radio' || objInp[i].type == 'checkbox') { // make sure we're dealing with radio boxes
			db = 'Name - ' + objInp[i].name + ' : ID - ' + objInp[i].id;
	//Fred C fix 
	if(objInp[i].nextSibling != null){
	//end Fred C fix 
			matches = objInp[i].nextSibling.innerHTML.match(seeker);
			if (matches) {
				db += ' : Adjusted!';
				objInp[i].onclick = function () { updateR(this); }
				if (objInp[i].checked)	updateR(objInp[i]);
			}
		}
//Fred C fix 
}
//end Fred C fix
		regdb('Onload RAD/CH', db);
	}

Fred. :smile:

29 May 2010, 5:10 AM
#632
milkyway avatar

milkyway

Inactive

Join Date:
Aug 2006
Location:
Singapore
Posts:
167
Plugin Contributions:
1

Re: Dynamic Price Updater

Ajeh:

The display is manage by the class in the template ... so I made the one at the top use a different class so the price did not change and put one at the bottom where the add to cart quantity is put in that had the class that gets changed ...

This way, the original price always shows on the page and the changing price of what the "actual" price will be based on quantity etc. would show right where the customer is working down by the attributes and add to cart quantity box ...

Hi Linda,

I failed to make DPU still showing the original price (didn't chnaged), instead of replacing it by just 'Your price: xxxx' because we have special price, so we can show how both original price and discount price.

I tried your method building a new class, above but couldn't get it to work, can you show me example of the file you modified?

I mean the file:
/classes/dynamic_price_updater.php

Thanks so much!

29 May 2010, 9:44 AM
#633
ajeh avatar

ajeh

Oba-san

Join Date:
Sep 2003
Location:
Ohio
Posts:
62,757
Plugin Contributions:
1

Re: Dynamic Price Updater

From what I remember on this one the:
zen_get_products_display_price

was in the :

<h2 id="productPrices" class="productGeneral">

and the update prices affect that ...

I just repeated the code without that and used a new class ...

29 May 2010, 3:54 PM
#634
mcqueeneycoins avatar

mcqueeneycoins

Zen Follower

Join Date:
Jan 2008
Posts:
156
Plugin Contributions:
0

Re: Dynamic Price Updater

I've installed this mod and it's working well. I've also installed this mod (http://www.zen-cart.com/forum/showthread.php?t=98641) to enable me to have a drop down menu on the product listing page rather than just the product info page. How would I go about having the price on that page dynamically update just like it does with the product info page?

30 May 2010, 6:58 PM
#635
mcqueeneycoins avatar

mcqueeneycoins

Zen Follower

Join Date:
Jan 2008
Posts:
156
Plugin Contributions:
0

Re: Dynamic Price Updater

To add a little bit more to my previous post...here is a link to my work-in-progress: https://www.mcqueeneycoins.com/index.php?main_page=index&cPath=1_2 showing the attribute drop-down mod in action.

On this page I want the prices to dynamically update when an attribute is selected, just as it does on the individual product's page. If anyone can shed some light on this for me I'm forever in your debt.

Thanks!

2 Jun 2010, 12:56 PM
#636
hugo13 avatar

hugo13

Zen Follower

Join Date:
Apr 2004
Location:
vienna
Posts:
176
Plugin Contributions:
4

Re: Dynamic Price Updater

i think ```php
$this->_responseText['priceTotal'] .= $currencies->display_price($this->_shoppingCart->total, $product_check->fields['products_tax_class_id']);

```php
$this->_responseText['priceTotal'] .= $currencies->display_price($this->_shoppingCart->total, 0);
```because, if $product_check->fields['products_tax_class_id'] > 0 , this tax-value is added to priceTotal; the tax was already added
5 Jun 2010, 12:33 AM
#637
amandagero avatar

amandagero

Zen Follower

Join Date:
Feb 2009
Posts:
188
Plugin Contributions:
0

Re: Dynamic Price Updater

has anyone got an idea how to get this working with dual pricing- wholesale, and replace product images on attribute change? i know this has been asked before and i know you have a long list of stuff to do dan, but if you could point me in the right direction i might be able to figure it out, also i am willing to make a donation if you could get these 2 working with this mod.

i have a test set up here:

http://southcrystals.com/index.php?main_page=product_info&cPath=6&products_id=22

i had both of these mods working before DPUv2

this is zc 1.3.8a

and if you need ftp in order to help me out just let me know.

also how do i remove the product quantity in parenthesis?

thank you so much for all of your time and energy into this dan, i have read through almost everythread of this topic and used a few of your fixes aready to get it working so far, but i do really need these other two working as well, as they took me forever to get working too.

5 Jun 2010, 2:19 AM
#638
amandagero avatar

amandagero

Zen Follower

Join Date:
Feb 2009
Posts:
188
Plugin Contributions:
0

Re: Dynamic Price Updater

ok, so i am assuming that the file that mainly needs to be edited is

includes/classes/dynamic_price_updater.php (to get the dual price - wholesale price mod to work)

here is what i have changed it to

<?php
// (c) D Parry (Chrome) 2009 ([email protected])
// This module is free to distribute and use as long as the above copyright message is left in tact
class DPU {
	/**
	* Current Zen Cart database object
	*
	* @var object
	*/
	var $_db;
	/**
	* Local copy of the POST array
	*
	* @var array
	*/
	var $_post = array();
	/**
	* Local instantiation of the shopping cart
	*
	* @var object
	*/
	var $_shoppingCart;
	/**
	* The type of message being sent (error or success)
	*
	* @var string
	*/
	var $_responseType = 'success';
	/**
	* Array of lines to be sent back.  The key of the array provides the attribute to identify it at the client side
	* The array value is the text to be inserted into the node
	*
	* @var array
	*/
	var $_responseText = array();

	/**
	* Constructor
	*
	* @param obj The Zen Cart database class
	* @return DPU
	*/
	function __construct(&$db) {
		$this->_db =& $db;
		$this->_post =& $_POST;

		// grab the shopping cart class and instantiate it
		require_once(DIR_WS_CLASSES.'shopping_cart.php');
		$this->_shoppingCart = new shoppingCart();
	}

	/**
	* PHP4 constructor
	*
	* @param obj ZC DB object
	* @return DPU
	*/
	function DPU(&$db) {
		$this->__construct($db);
	}

	/**
	* Wrapper to call all methods to generate the output
	*
	* @return void
	*/
	function getDetails() {
		$this->insertProduct();
		$this->_shoppingCart->calculate();
        if (DPU_SHOW_SIDEBOX)   $this->getSideboxContent();

		$this->prepareOutput();
		$this->dumpOutput();
	}

	/**
	* Wrapper to call all methods relating to returning multiple prices for category pages etc.
	*
	* @return void
	*/
	function getMulti() {
		$this->insertProducts();
	}

	/**
	* Prepares the shoppingCart contents for transmission
	*
	* @return void
	*/
	function prepareOutput() {
		global $currencies;
		$this->_responseText['priceTotal'] = UPDATER_PREFIX_TEXT;
		$product_check = $this->_db->Execute("select products_tax_class_id from " . TABLE_PRODUCTS . " where products_id = '" . (int)$this->_post['products_id'] . "'" . " limit 1");
		if (false == DPU_SHOW_CURRENCY_SYMBOLS) {
			$this->_responseText['priceTotal'] .= number_format($this->_shoppingCart->total, 2);
		} else {
			$this->_responseText['priceTotal'] .= $currencies->display_price($this->_shoppingCart->total, $product_check->fields['products_tax_class_id']);
		}

		$this->_responseText['weight'] = (string)$this->_shoppingCart->weight;
		if (DPU_SHOW_QUANTITY) {
			$this->_responseText['quantity'] = sprintf(DPU_SHOW_QUANTITY_FRAME, $this->_shoppingCart->contents[$this->_post['products_id']]['qty']);
		}
	}

	/**
	* Inserts multiple non-attributed products into the shopping cart
	*
	* @return void
	*/
	function insertProducts() {
		foreach ($this->_post['products_id'] as $id => $qty) {
			$this->_shoppingCart->contents[] = array($id);
			$this->_shoppingCart->contents[$id] = array('qty' => (float)$qty);
		}

		var_dump($this->_shoppingCart);
		die();
	}

	/**
	* Inserts the product into the shoppingCart content array
	*
	* @returns void
	*/
	function insertProduct() {
      	$this->_shoppingCart->contents[$this->_post['products_id']] = array('qty' => (float)$this->_post['cart_quantity']);
      	$attributes = array();

      	foreach ($this->_post as $key => $val) {
			if (is_array($val)) {
				foreach ($val as $k => $v) {
					$attributes[$k] = $v;
				}
			}
      	}

      	if (is_array($attributes)) {
        	reset($attributes);
        	while (list($option, $value) = each($attributes)) {
          		//CLR 020606 check if input was from text box.  If so, store additional attribute information
          		//CLR 020708 check if text input is blank, if so do not add to attribute lists
          		//CLR 030228 add htmlspecialchars processing.  This handles quotes and other special chars in the user input.
          		$attr_value = NULL;
          		$blank_value = FALSE;
          		if (strstr($option, TEXT_PREFIX)) {
            		if (trim($value) == NULL) {
              			$blank_value = TRUE;
            		} else {
              			$option = substr($option, strlen(TEXT_PREFIX));
				    	$attr_value = stripslashes($value);
				    	$value = PRODUCTS_OPTIONS_VALUES_TEXT_ID;
				      	$this->_shoppingCart->contents[$this->_post['products_id']]['attributes_values'][$option] = $attr_value;
            		}
          		}

          		if (!$blank_value) {
            		if (is_array($value) ) {
              			reset($value);
              			while (list($opt, $val) = each($value)) {
                			$this->_shoppingCart->contents[$this->_post['products_id']]['attributes'][$option.'_chk'.$val] = $val;
              			}
            		} else {
              			$this->_shoppingCart->contents[$this->_post['products_id']]['attributes'][$option] = $value;
            		}
          		}
	        }
	    }

    	// $this->_shoppingCart->cleanup();
	}
    
    /**
    * Prepares the output for the Updater's sidebox display
    * 
    */
    function getSideboxContent() {
        global $currencies;
        
        $product_check = $this->_db->Execute("select products_tax_class_id from " . TABLE_PRODUCTS . " where products_id = '" . (int)$this->_post['products_id'] . "'" . " limit 1");
        $product_query = "select products_id, products_price, products_tax_class_id, products_weight,
                          products_priced_by_attribute, product_is_always_free_shipping, products_discount_type, products_discount_type_from,
                          products_virtual, products_model
                          from " . TABLE_PRODUCTS . "
                          where products_id = '" . (int)$this->_post['products_id'] . "'";

        $product = $this->_db->Execute($product_query);
        $prid = $product->fields['products_id'];
        $products_tax = zen_get_tax_rate($product->fields['products_tax_class_id']);
//    $products_price = $product->fields['products_price']; - REMOVED FOR DUAL PRICING MOD
//*************************************************************
//***** CHECK WHETHER WHOLESALE OR RETAIL AND GET CORRECT PRICE
//*************************************************************
if ($_SESSION['customer_id']) {
    $customers_id = $_SESSION['customer_id'];
	$customer_check = $db->Execute("select * from " . TABLE_CUSTOMERS . " where customers_id = '$customers_id'");
		if ($customer_check->fields['customers_whole'] != "0") {
			$i = $customer_check->fields['customers_whole'];
			$i = $i-1;			
      		$products_price_array = $product->fields['products_price_w'];
			$productsprice = explode("-",$products_price_array);
			$products_price = $productsprice[$i];
			if ($products_price == '0' || $products_price == '') {
				$products_price = $productsprice[0];
			}
			
			if ($products_price=='0'){
				$products_price = $product->fields['products_price'];
			}
			
		} else {
      		$products_price = $product->fields['products_price'];
		}

} else {
	$products_price = $product->fields['products_price'];
}
//****************************************************************
//*****END CHECK WHETHER WHOLESALE OR RETAIL AND GET CORRECT PRICE
//****************************************************************


		
        $qty = $this->_post['cart_quantity'];
        $out = array();
        $global_total;
        reset($this->_shoppingCart->contents[$this->_post['products_id']]['attributes']);
        while (list($option, $value) = each($this->_shoppingCart->contents[$this->_post['products_id']]['attributes'])) {
            $adjust_downloads ++;

            $attribute_price_query = "select *
                                      from " . TABLE_PRODUCTS_ATTRIBUTES . "
                                      where products_id = '" . (int)$prid . "'
                                      and options_id = '" . (int)$option . "'
                                      and options_values_id = '" . (int)$value . "'";

            $attribute_price = $this->_db->Execute($attribute_price_query);
            
            $sql = "SELECT
                    `products_options_values_name`
                FROM
                    ".TABLE_PRODUCTS_OPTIONS_VALUES."
                WHERE
                    `products_options_values_id` = $value";
            $data = $this->_db->Execute($sql);
            $name = $data->fields['products_options_values_name'];

            $new_attributes_price = 0;
            $discount_type_id = '';
            $sale_maker_discount = '';
            $total = 0;

            if ($attribute_price->fields['product_attribute_is_free'] == '1' and zen_get_products_price_is_free((int)$prid)) {
                // no charge for attribute
            } else {
                // + or blank adds
                if ($attribute_price->fields['price_prefix'] == '-') {
                    // appears to confuse products priced by attributes
                    if ($product->fields['product_is_always_free_shipping'] == '1' or $product->fields['products_virtual'] == '1') {
                        $shipping_attributes_price = zen_get_discount_calc($product->fields['products_id'], $attribute_price->fields['products_attributes_id'], $attribute_price->fields['options_values_price'], $qty);
                        $this->free_shipping_price -= $qty * zen_add_tax( ($shipping_attributes_price), $products_tax);
                    }
                    if ($attribute_price->fields['attributes_discounted'] == '1') {
                        // calculate proper discount for attributes
                        $new_attributes_price = zen_get_discount_calc($product->fields['products_id'], $attribute_price->fields['products_attributes_id'], $attribute_price->fields['options_values_price'], $qty);
                        $total -= $qty * zen_add_tax( ($new_attributes_price), $products_tax);
                    } else {
                        $total -= $qty * zen_add_tax($attribute_price->fields['options_values_price'], $products_tax);
                    }
                    $total = '-'.$total;
                } else {
                    // appears to confuse products priced by attributes
                    if ($product->fields['product_is_always_free_shipping'] == '1' or $product->fields['products_virtual'] == '1') {
                        $shipping_attributes_price = zen_get_discount_calc($product->fields['products_id'], $attribute_price->fields['products_attributes_id'], $attribute_price->fields['options_values_price'], $qty);
                        $this->free_shipping_price += $qty * zen_add_tax( ($shipping_attributes_price), $products_tax);
                    }
                    if ($attribute_price->fields['attributes_discounted'] == '1') {
                        // calculate proper discount for attributes
                        $new_attributes_price = zen_get_discount_calc($product->fields['products_id'], $attribute_price->fields['products_attributes_id'], $attribute_price->fields['options_values_price'], $qty);
                        $total += $qty * zen_add_tax( ($new_attributes_price), $products_tax);
                        // echo $product->fields['products_id'].' - '.$attribute_price->fields['products_attributes_id'].' - '. $attribute_price->fields['options_values_price'].' - '.$qty."\n";
//    $products_price = $product->fields['products_price']; - REMOVED FOR DUAL PRICING MOD
//*************************************************************
//***** CHECK WHETHER WHOLESALE OR RETAIL AND GET CORRECT PRICE
//*************************************************************
if ($_SESSION['customer_id']) {
    $customers_id = $_SESSION['customer_id'];
	$customer_check = $db->Execute("select * from " . TABLE_CUSTOMERS . " where customers_id = '$customers_id'");
		if ($customer_check->fields['customers_whole'] != "0") {
			$i = $customer_check->fields['customers_whole'];
			$i = $i-1;			
      		$products_price_array = $products->fields['products_price_w'];
			$productsprice = explode("-",$products_price_array);
			$products_price = $productsprice[$i];
			if ($products_price == '0' || $products_price == '') {
				$products_price = $productsprice[0];
			}
			
			if ($products_price=='0'){
				$products_price = $products->fields['products_price'];
			}
			
		} else {
      		$products_price = $products->fields['products_price'];
		}

} else {
	$products_price = $products->fields['products_price'];
}
//****************************************************************
//*****END CHECK WHETHER WHOLESALE OR RETAIL AND GET CORRECT PRICE
//****************************************************************

                    } else {
                        $total += $qty * zen_add_tax($attribute_price->fields['options_values_price'], $products_tax);
                    }
                }
            }
            $global_total += $total;
            $qty2 = sprintf(DPU_SIDEBOX_QUANTITY_FRAME, $this->_post['cart_quantity']);
            $total = sprintf(DPU_SIDEBOX_PRICE_FRAME, $currencies->display_price($total, $product_check->fields['products_tax_class_id']));
            $out[] = sprintf(DPU_SIDEBOX_FRAME, $name, $total, $qty2);
        }
        
        $out[] = sprintf(DPU_SIDEBOX_TOTAL_FRAME, $currencies->display_price($this->_shoppingCart->total, $product_check->fields['products_tax_class_id']));
        
        $qty2 = sprintf(DPU_SIDEBOX_QUANTITY_FRAME, $this->_post['cart_quantity']);
        $total = sprintf(DPU_SIDEBOX_PRICE_FRAME, $currencies->display_price($this->_shoppingCart->total-$global_total, $product_check->fields['products_tax_class_id']));
        array_unshift($out, sprintf(DPU_SIDEBOX_FRAME, 'Base price', $total, $qty2));
        
        $this->_responseText['sideboxContent'] = implode('', $out);
    }

	/**
	* Performs an error dump
	*
	* @param mixed $errorMsg
	*/
	function throwError($errorMsg) {
		$this->_responseType = 'error';
		$this->_responseText[] = $errorMsg;

		$this->dumpOutput();
	}

	/**
	* Formats the response and flushes with the appropriate headers
	* This should be called last as it issues an exit
	*
	* @return void
	*/
	function dumpOutput() {
		// output the header for XML
		header ("content-type: text/xml");
		// set the XML file DOCTYPE
		echo '<?xml version="1.0" encoding="UTF-8" ?>'."\n";
		// set the responseType
		echo '<root>'."\n".'<responseType>'.$this->_responseType.'</responseType>'."\n";
		// now loop through the responseText nodes
		foreach ($this->_responseText as $key => $val) {
			echo '<responseText'.(!is_numeric($key) && !empty($key) ? ' type="'.$key.'"' : '').'><![CDATA['.$val.']]></responseText>'."\n";
		}

		die('</root>');
	}
}

i know i am not doing this right, i see that i have inserted the wholesale code into a function, and im not good with this stuff, but i will keep playing around.

5 Jun 2010, 2:38 AM
#639
amandagero avatar

amandagero

Zen Follower

Join Date:
Feb 2009
Posts:
188
Plugin Contributions:
0

Re: Dynamic Price Updater

i have figured why (i think) i cannot get this to work.

it is calculating from priceTotal which is from the price update mod only, so it will not show any other prices. i am unsure how to merge these....

i will leave it alone for now, but ANY ideas are welcome, thank you!

17 Jun 2010, 3:48 PM
#640
ppsoyal avatar

ppsoyal

New Zenner

Join Date:
May 2010
Posts:
33
Plugin Contributions:
0

Re: Dynamic Price Updater

Hi!,

I install this tool and works ok, but then the "attribute replace main product image" don´t work.

I want that when customer select an attribute, for example a color that is moore expensive, the main product image and price change to the new image and price.

Separately the DPU and "attribute replace main product image" works ok, but not together.

Anyone knows how can I obtain this effect or why this two modules don´t work together?

Thank you very much.