We currently only have one product so our users can only be subscribed to one thing at a time. I imagine multi-product users would want a sum of current liability, but this works for us. Version: 3.1.8PRO Backup your site before making any modifications! STEP 1 - Calculate Liability and add to Display Array In /amember/admin/users.php, find this function: Code: function display_payments_form(){ global $member_id; global $db, $t; if ($_GET['cancel_recurring'] > 0){ $p = $db->get_payment($_GET['cancel_recurring']); if (!$p) die('Cannot find payment to cancel recurring. internal error'); $p['data']['CANCELLED'] = 1; $p['data']['CANCELLED_AT'] = strftime($config['time_format'], time()); $db->update_payment($p['payment_id'], $p); admin_log("Subscription cancelled", 'payments', $p['payment_id']); } $products = & $db->get_products_list(); $pp = array(); foreach ($products as $p) $pp[ $p['product_id'] ] = $p['title'] ; $t->assign('products', $pp); $t->assign('member_id', $member_id); $payments = & $db->get_user_payments(intval($member_id)); foreach ($payments as $k=>$p){ $payments[$k]['items_count'] = count($p['data'][0]['BASKET_PRODUCTS']); /** Following is a dirty hack to show cancel link in admin cp */ if ($payments[$k]['expire_date'] >= date('Y-m-d')){ $paysys = get_paysystem($p['paysys_id']); $product = $db->get_product($p['product_id']); if ($paysys['recurring'] && ($pay_plugin = &instantiate_plugin('payment', $p['paysys_id'])) && $product['is_recurring'] && method_exists($pay_plugin, 'get_cancel_link')){ $l = $pay_plugin->get_cancel_link($p['payment_id']); if (preg_match('|cc.php\?action=cancel_recurring|', $l, $regs)){ $u = $_SERVER['PHP_SELF'] . "?member_id=$member_id&action=payments&" . 'cancel_recurring=' . $p['payment_id']; $payments[$k]['cancel_url'] = $u; } } } } $t->assign('payments', $payments); $paysystems = get_paysystems_list(); $pp = array(); foreach ($paysystems as $p) $pp[ $p['paysys_id'] ] = $p['title'] ; $t->assign('paysystems', $pp); global $payment_additional_fields; $t->assign('payment_additional_fields', $payment_additional_fields); $t->display('admin/user_payments.html'); } CHANGE it to this: Code: function display_payments_form(){ global $member_id; global $db, $t; if ($_GET['cancel_recurring'] > 0){ $p = $db->get_payment($_GET['cancel_recurring']); if (!$p) die('Cannot find payment to cancel recurring. internal error'); $p['data']['CANCELLED'] = 1; $p['data']['CANCELLED_AT'] = strftime($config['time_format'], time()); $db->update_payment($p['payment_id'], $p); admin_log("Subscription cancelled", 'payments', $p['payment_id']); } $products = & $db->get_products_list(); $pp = array(); foreach ($products as $p) $pp[ $p['product_id'] ] = $p['title'] ; $t->assign('products', $pp); $t->assign('member_id', $member_id); $payments = & $db->get_user_payments(intval($member_id)); foreach ($payments as $k=>$p){ $payments[$k]['items_count'] = count($p['data'][0]['BASKET_PRODUCTS']); /** Following is a dirty hack to show cancel link in admin cp */ if ($payments[$k]['expire_date'] >= date('Y-m-d')){ $paysys = get_paysystem($p['paysys_id']); $product = $db->get_product($p['product_id']); if ($paysys['recurring'] && ($pay_plugin = &instantiate_plugin('payment', $p['paysys_id'])) && $product['is_recurring'] && method_exists($pay_plugin, 'get_cancel_link')){ $l = $pay_plugin->get_cancel_link($p['payment_id']); if (preg_match('|cc.php\?action=cancel_recurring|', $l, $regs)){ $u = $_SERVER['PHP_SELF'] . "?member_id=$member_id&action=payments&" . 'cancel_recurring=' . $p['payment_id']; $payments[$k]['cancel_url'] = $u; } } } // If this is a completed payment we are responsible for, calculate liability. if( $payments[$k]['completed'] ){ // Create begin date as UNIX time for easier calculations. list( $beg_year, $beg_month, $beg_day ) = split( "-", $p['begin_date'] ); $unix_begin_date = mktime( 0, 0, 0, $beg_month, $beg_day, $beg_year ); // Create expiration date as UNIX time for easier calculations. list( $exp_year, $exp_month, $exp_day ) = split( "-", $p['expire_date'] ); $unix_expire_date = mktime( 0, 0, 0, $exp_month, $exp_day, $exp_year ); // Create today as UNIX time for easier calculations. $unix_today = time(); // Calculate ACTUAL number of days purchased (not based off assumed subscription length of product). $liability_full = floor( ( $unix_expire_date - $unix_begin_date ) / ( 60*60*24 ) ); // If expiration date is in the past, no liability if( $unix_today >= $unix_expire_date ){ //echo( "Expiration is today or in the past...<br>" ); $liability_days = 0; $liability_percent = 0; // If start date is in the future, full liability } elseif( $unix_begin_date > $unix_today ){ //echo( "Subscription starts in the future...<br>" ); $liability_days = $liability_full; $liability_percent = 1; // Otherwise, calculate the days left until expiration } else { //echo( "We are in the subscription...<br>" ); $liability_days = floor( ( $unix_expire_date - $unix_today ) / ( 60*60*24 ) ); $liability_percent = $liability_days / $liability_full; } // Calculate liability days and put text into array. if( $liability_days <= 0 ){ $payments[$k]['liability_days'] = "None"; } elseif( $liability_days == 1 ){ $payments[$k]['liability_days'] = $liability_days . " Day"; } else { $payments[$k]['liability_days'] = $liability_days . " Days"; } // Calculate liability cost and put integer into array. $payments[$k]['liability_cost'] = number_format( round( $payments[$k]['amount'] * $liability_percent, 2 ), 2 ); // Calculate rate per day of subscription. $payments[$k]['rate_per_day'] = round( ( $payments[$k]['amount'] / $liability_full ), 2 ) * 100; } } $t->assign('payments', $payments); $paysystems = get_paysystems_list(); $pp = array(); foreach ($paysystems as $p) $pp[ $p['paysys_id'] ] = $p['title'] ; $t->assign('paysystems', $pp); global $payment_additional_fields; $t->assign('payment_additional_fields', $payment_additional_fields); $t->display('admin/user_payments.html'); } STEP 2 - Update User Payments Display to show Liability In /amember/templates/user_payments.html, around line 17, AFTER: Code: <th>Status</th> ADD: Code: <th>Liability</th> Then around line 41, CHANGE: Code: <td>{$config.currency|default:"$"}{$p.amount}</td> <td align=center>{if $p.completed}<b>YES</b>{else}NO{/if}</td> <td>{if $p.completed} {if $p.expire_date >= date('Y-m-d') and $p.begin_date <= date('Y-m-d') } <b>Active</b> {elseif $p.expire_date < date('Y-m-d') } <font color=red><b>Expired</b></font> {elseif $p.begin_date > date('Y-m-d') } Future {/if} {else} Not-Paid {/if} {if $p.data.CANCELLED}<br /><font color=red>CANCELLED</font>{/if} {if $p.cancel_url && $p.completed}<br /><a href="{$p.cancel_url|escape}">Stop Recurring</a>{/if} </td> to Code: <td>{$config.currency|default:"$"}{$p.amount} {if $p.completed}<br /><span style="font-size: 10px;">{$p.rate_per_day}¢/day</span>{/if}</td> <td align=center>{if $p.completed}<b>YES</b>{else}NO{/if}</td> <td>{if $p.completed} {if $p.expire_date >= date('Y-m-d') and $p.begin_date <= date('Y-m-d') } <b>Active</b> {elseif $p.expire_date < date('Y-m-d') } <font color=red><b>Expired</b></font> {elseif $p.begin_date > date('Y-m-d') } Future {/if} {else} Not-Paid {/if} {if $p.data.CANCELLED}<br /><font color=red>CANCELLED</font>{/if} {if $p.cancel_url && $p.completed}<br /><a href="{$p.cancel_url|escape}">Stop Recurring</a>{/if} </td> <td>{if $p.liability_days == 'None'}{$p.liability_days} {elseif $p.completed && $p.liability_days != 'None'}{$config.currency|default:"$"}{$p.liability_cost}<br /> <span style="font-size: 10px;">{$p.liability_days}</span>{/if} </td> Finally, around line 69, CHANGE: Code: <th colspan=8 align=center to Code: <th colspan=9 align=center