Akopia Akopia Services

[Date Prev][Date Next][Thread Prev][Thread Next][Minivend by date ][Minivend by thread ]

[mv] Buy 3 get 1 (almost free)! -- Have working code



Well, you wanted it (at least someone did in the past),
you've got it (have tested on MV3.11 and it seems to work)

You will find attached a usertag in bsgsc_usertag.txt
(bsgsc - Buy Some Get Some Cheap)

NOTE: Use at your own risk, the code will modify
the cart contents!
(let me know of any bugs)

Place user tag in catalog or minivend .cfg file

Set CommonAdjust up as follows:
CommonAdjust   $ ;products:price
(and reconfig/restart).
and set price field so CommonAdjust will work:
PriceField   no_price

(It probably won't work with additional 'atoms'
because it only looks in products table for the
price when calculating the Free* items and
after it is done and additional adjustment may
change the Free* price)

*- the price is set to $.01 because that is the only way
I could get CommonAdjust to work correctly. If I set it
to $0.00 it would fall back to the regular price, maybe
someone knows a way around this?

Place this tag at the top of the basket page like:
[bsgsc 3]

(It takes 1 argument which is the quantity which
will trigger the Free* items, in this case buy 3
get 1 for $ .01)

The code will take care of customers trying to
cheat the system, because it will run through
the entire cart and recalculate the contents
at the regular price before allowing Free* items.

It will also only allow the Free* items to be the
lowest priced items in the basket so you won't
sell 3 - $1.00 items and give away 1 - $100.00 item!


You can also place something like this on the basket
or any other page to inform customers that they
have "reached" the next level:

[if session freebies]
	<b>You qualify for 1 more item priced
	at or less than
	[currency][data session freebies][/currency]
	for only $.01!</b>
[/if]

One additional note:
The code will automatically combine similar items
(only if their attributes match) and divide them
(where some are Free*) regardless of whether
you have SeperateItems set or not!

Enjoy and let me have your feedback (I think I can take it)

Kyle (KC)


UserTag bsgsc Order quantity
UserTag bsgsc Routine <<EOR
sub {
my ($qualify) = @_;
my $cart = $Vend::Items;
my ($item,$move,$max,$last);
my $so_far = 0;
my $count = 0;

# Erase all mv_prices to calculate prices (before this discount)!
# And combine all similar products if attributes match
for (my $x=0;$x < @$cart;$x++) {
	# Get a total count of items (not line orders) in cart
	$count += $$cart[$x]{quantity};
	$$cart[$x]{mv_price} = Vend::Interpolate::tag_data('products', 'price', $$cart[$x]{code});
	REMAIN: for (my $y=$x+1;$y < @$cart;$y++) {
		next REMAIN unless ($$cart[$x]{code} eq $$cart[$y]{code});
		foreach (keys %{ $$cart[$y] }) {
			next REMAIN unless ($_ =~ /quantity|mv_price/i ||
				$$cart[$x]{$_} eq $$cart[$y]{$_});
		}
		# we have checked all attributes, so combine items
		$$cart[$x]{quantity} += $$cart[$y]{quantity};
		# have to include this quantity because this item is being combined
		# and the outer loop will miss it!
		$count += $$cart[$y]{quantity};
		splice(@$cart, $y, 1);
	}
}

# calculate number of items to offer for free
my $set_free = int($count/($qualify + 1));
my $free = $count % $qualify ? 0:1;

# Set the first $set_free items in the cart to
# 0.01 for mv_price.
# Must be 0.00 or CommonAdjust will ignore!
# Also must now set mv_price to '' for rest of items
# so regular price routines will apply!

# sort by price (lowest first) that way we simply set
# the first x items to be free!
foreach $item (sort { $a->{mv_price} <=> $b->{mv_price} } @$cart) {
	if ($so_far < $set_free) {
		$last = $item->{mv_price};
		if ( $item->{quantity} > ($set_free - $so_far)) {
			# We need to split this one because quantity too high!
			$move = {%$item};
			$move->{quantity} = ($item->{quantity} - ($set_free - $so_far));
			$move->{mv_price} = '';
			$item->{quantity} = ($set_free - $so_far);
			$item->{mv_price} = '0.01';
			push (@$cart, {%$move});
			$so_far = $set_free;
		}
		else {
			$item->{mv_price} = '0.01';
			$so_far += $item->{quantity};
		}
		$max = $last unless ($max && $last > $max);
	}
	else {
		$item->{mv_price} = '';
	}
}
$Vend::Session->{freebies} = $free ? $max : '';
return '';
}
EOR

Search for: Match: Format: Sort by: