Jump to content

tiger_walts

Member
  • Posts

    3
  • Joined

  • Last visited

About tiger_walts

tiger_walts's Achievements

Junior Member

Junior Member (1/3)

1

Reputation

  1. My original calculations were too naive. After some more experimentation it became clear that to calculate the correct value you need to know the following values: Current service price New Service Price Days left on current cycle Total days in current cycle Total days in new Cycle Discount rate I now have a revised hook that appears to be working (with some rounding errors): function myAddon_OrderProductUpgradeOverride ($vars) { $return = array(); $pid = $vars['newproductid']; $daysLeft = $vars['daysuntilrenewal']; $oldTotalDays = $vars['totalDays']; $newCycleMonths = 1; $newBillingCycle = $vars['newproductbillingcycle']; switch($newBillingCycle) { // convert billing cycle to number of months case 'quarterly': $newCycleMonths = 3; break; case 'semiannually': $newCycleMonths = 6; break; case 'annually': $newCycleMonths = 12; break; case 'biennially': $newCycleMonths = 24; break; case 'triennially': $newCycleMonths = 36; break; } $price = $vars['price']; $di****ount = $vars['discount']; $today = new DateTime(); $newStart = new DateTime(); $newStart->sub(new DateInterval('P'.$newCycleMonths.'M')); $DInewTotalDays = $newStart->diff($today); $newTotalDays = 1 + $DInewTotalDays->days; // get the number of days over the new billing cycle $return['newCycleMonths'] = $newCycleMonths; $return['newTotalDays'] = $newTotalDays; if (isset($_SESSION['uid'])) { // get the currency from the logged in client $uid = $_SESSION['uid']; $user = Capsule::table('tblclients') ->where('id', $uid) ->first(); $curr = $user->currency; } $return['uid'] = $uid; $return['curr'] = $curr; if (isset($curr)) { // get the price of the new product $pricing = Capsule::table('tblpricing') ->where('relid', $pid) ->where('type', 'product') ->where('currency', $curr) ->first(); switch($newBillingCycle) { case 'monthly': $newFullPrice = $pricing->monthly; break; case 'quarterly': $newFullPrice = $pricing->quarterly; break; case 'semiannually': $newFullPrice = $pricing->semiannually; break; case 'annually': $newFullPrice = $pricing->annually; break; case 'biennially': $newFullPrice = $pricing->biennially; break; case 'triennially': $newFullPrice = $pricing->triennially; break; } } $return['newFullPrice'] = $newFullPrice; if ($price != 0 && isset($newFullPrice)) { $debit = round($newFullPrice * $daysLeft / $newTotalDays, 2); // calculate what the debit amount was $credit = $debit - $price; // calculate what the credit was (the old price may have changed) $discRate = round($di****ount / $price, 2); //assumes a discount rate with no decimal part $newDebit = round((1 - $discRate) * $newFullPrice * $daysLeft / $newTotalDays, 2); $newPrice = round(($newDebit - $credit) / (1 - $discRate), 2); $newDi****ount = round($newPrice * $discRate, 2); $return['debit'] = $debit; $return['credit'] = $credit; $return['discRate'] = $discRate; $return['newDebit'] = $newDebit; $return['price'] = $newPrice; $return['discount'] = $newDi****ount; } logModuleCall('myAddon', 'OrderProductUpgradeOverride', $vars, $vars, $return, array()); return $return; } add_hook('OrderProductUpgradeOverride', 1, 'myAddon_OrderProductUpgradeOverride'); Initial checks seem good so far. Changing to a new billing cycle looks good too.
  2. We had the same problem. We were using a path with a symlink in it. When we changed it to the full path it started working. The other paths in the configuration.php that were using symlinks appeared to be OK, but we have changed them to the full path in case they are affected similarly.
  3. When placing pro-rated upgrade order that also has a recurring discount, the calculated price is incorrect. The formula being used is: Old Product/Service Price Per Day * Number of days until next due date = Amount Credited New Product/Service Price Per Day * Number of days until next due date = Amount Debited Total Payable Today = Amount Debited - Amount Credited Discounted Upgrade Price = Total Payable Today - Discount This is fine for a one-off discount on the upgrade itself, but is incorrect for a pro-rated upgrade on the service where the discount should be applied to the Amount Debited. An older thread discussed the issue. These values can be overridden when the user selects the product to upgrade to using the OrderProductUpgradeOverride hook. Here's an example of the variables passed to it: Array ( [oldproductid] => 159 [oldproductname] => Old product [newproductid] => 161 [newproductname] => New Product [daysuntilrenewal] => 25 [totaldays] => 31 [newproductbillingcycle] => monthly [price] => 6.52 [discount] => 1.63 [promoqualifies] => 1 ) price is the Total Payable Today from above. There's not much to go on here, but in our situation we have no absolute value discounts (just percentages). We can use the price and discount to get the discount percentage and from that calculate what the price and discount should be: Discount Rate = discount / price New Price = price / (1 + Discount Rate) New Discount = New Price * Discount This is far from perfect, price and discount have already been rounded, so any value derived from them will have a margin of error. Here's the hook code: function myAddon_OrderProductUpgradeOverride ($vars) { $return = array(); if ($vars['price'] == 0) { $discRate = 0; } else { $discRate = $vars['discount'] / $vars['price']; } $return['price'] = round( $vars['price'] / ($discRate + 1) , 2); $return['discount'] = round( $return['price'] * $discRate, 2); logModuleCall('myAddon', 'OrderProductUpgradeOverride', '', $vars, $return, array()); return $return; } add_hook('OrderProductUpgradeOverride', 1, 'myAddon_OrderProductUpgradeOverride'); If anyone can spot any problems or offer any improvements to the above, I'd be happy to hear them. I can get the new product information using the newproductid but no way to get the correct currency value. If the customer is ordering the upgrade we can get their currency, but if an admin orders it from within WHMCS it's not possible. If the hook passed the promotion code and the price for the full payment period, the calculation could be more robust.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated