Okay, I worked on your test site today.
I didn’t change every level, although they’re all basically the same, only thing that changes is length of time. I did need to free up level 1 for the intermediate demotion, so I moved the level 1 users to level 2.
Using the s2Member user import/export tool, I put all the “current” customers (levels 1 and 2) together in a single role (s2member Level 2), and gave them the custom capabilities “annual” and “triennial” as a label to tell them apart (I could have done the same for “contra”, “life” and “exempt” but didn’t bother, feel free to if you want.) WP Admin > s2Member Pro > Import/Export
I hope that makes sense and I didn’t confuse you.
I renamed Level 1 from “Current Annual” to “Overdue”, and renamed Level 2 from “Current Triennial” to “Current”. WP Admin > s2Member > General > Membership Levels/Labels
I changed the Grace Time in the EOT setting, to just 1 day. WP Admin > s2Member > PayPal Options > Auto EOT Behavior
I added the file s2-hacks.php to your /wp-content/must-use/
plugins folder with this code:
<?php
add_action('ws_plugin__s2member_during_auto_eot_system_during_demote', 's2_custom_eot_demotion_role');
add_action('ws_plugin__s2member_during_paypal_notify_during_subscr_eot_demote', 's2_custom_eot_demotion_role');
function s2_custom_eot_demotion_role(array $vars) {
$user = $vars['user']; // WP_User object instance.
$role_before_demotion = $vars['existing_role']; // Role ID before demotion by s2Member.
if ($role_before_demotion === 's2member_level2') {
// If he was at level 2, demote to 1 and give him 3 months to pay.
$user->set_role('s2member_level1');
update_user_option($user->ID, 's2member_auto_eot_time', strtotime('+3 months'));
} else if ($role_before_demotion === 's2member_level1') {
// If he didn't pay after 3 months, demote to 0.
$user->set_role('subscriber');
}
}
I created a test user and gave him the role Current (level 2) and an EOT time in the past, and after a while, wp-cron kicked in and demoted him to Overdue (level 1) with an EOT 3 months ahead. Then I changed his EOT time to the past again, and after a while he got demoted to Subscriber (level 0). So it seems to be behaving as desired.
Please run your own tests, check what I did, and ask me anything you want.
I hope that helps!