Last active
August 29, 2015 14:13
-
-
Save elzekool/12303b819476b4f70249 to your computer and use it in GitHub Desktop.
Make an commercial price of original price with margin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Make nice commercial price from orignal price | |
* | |
* @param string $price Original price | |
* @param string $rangeDown Range down in percent | |
* @param string $rangeUp Range up in percent | |
* @param string $minUnit Minimal unit to increment up/down | |
* | |
* @return string Commercial price | |
**/ | |
function commercialize($price, $rangeDown = '10', $rangeUp = '0', $minUnit = '1.00') | |
{ | |
// Make price universal format, with two decimals | |
// this allows str_replace later on | |
$price = bcmul($price, '1.00', 2); | |
// First determine upper and lower boundaries | |
$minPrice = bcsub($price, bcmul($price, bcdiv($rangeDown, '100', 3), 2)); | |
$maxPrice = bcadd($price, bcmul($price, bcdiv($rangeUp, '100', 3), 2)); | |
// Prices found in range | |
$prices = []; | |
// Go trough multiplication factors | |
for($x = 9; $x >= 2; $x--) { | |
// Base is used to substract one or add one to the current number to test | |
$base = bcmul('1.00', bcmul($minUnit, bcpow('10.00', $x, 2)), 2); | |
// Replace is used to replace everything after the base with 99 | |
$replace = bcmul(preg_replace('/0/', '9', str_replace('1', '', $base), $x), '1.00', 2); | |
// Make sure auto added 0. is correctly handled | |
if (strpos($replace, '0.') === 0) { | |
$replace = substr($replace, 1); | |
} | |
// Create prices to test | |
$testPrices = [ | |
$price, | |
bcsub($price, $base, 2), | |
bcadd($price, $base, 2) | |
]; | |
// Test prices, and store them if the fall in range | |
foreach($testPrices as $testPrice) { | |
$testPrice = substr($testPrice, 0, strlen($testPrice) - strlen($replace)) . $replace; | |
if (bccomp($testPrice, $maxPrice, 2) > 0) { continue; } | |
if (bccomp($minPrice, $testPrice, 2) > 0) { continue; } | |
$prices[] = $testPrice; | |
} | |
} | |
// If no prices are found, just return the original | |
if (count($prices) == 0) { return $price; } | |
// Now test which price has the lowest difference with the | |
// original value | |
$diff = str_replace('-', '', bcsub($price, $prices[0], 2)); | |
$out = $prices[0]; | |
foreach($prices as $n_price) { | |
$n_diff = str_replace('-', '', bcsub($price, $n_price, 2)); | |
if (bccomp($diff, $n_diff, 2) > 0) { | |
$diff = $n_diff; | |
$out = $n_price; | |
} | |
} | |
return $out; | |
} | |
header("Content-type: text/plain"); | |
$tests = [ | |
[ '12.21', '25', '25', '0.01' ], | |
[ '1518', '25', '25', '1.00' ], | |
[ '1684', '25', '25', '1.00' ], | |
[ '7193', '25', '25', '1.00' ], | |
[ '8018', '25', '25', '1.00' ], | |
[ '8.21', '25', '25', '0.01' ], | |
[ '21.50', '25', '25', '0.01' ], | |
]; | |
foreach($tests as $test) { | |
list($price, $minRange, $maxRange, $minUnit) = $test; | |
$commercial = commercialize($price, $minRange, $maxRange, $minUnit); | |
echo sprintf('%s --> %s', str_pad($price, 8, ' '), $commercial) . "\n"; | |
} | |
// OUTPUT: | |
// 12.21 --> 11.99 | |
// 1518 --> 1499.00 | |
// 1684 --> 1699.00 | |
// 7193 --> 7199.00 | |
// 8018 --> 7999.00 | |
// 8.21 --> 7.99 | |
// 21.50 --> 21.99 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment