</th> </tr> </thead> <tbody> <?php $c = 0; foreach ($pagination['rows'] as $subscription) { ?> <tr class="<?php echo $c++ % 2 ? "odd" : "even"; ?> "> <td class="row_action"> <?php echo module_subscription::link_open($subscription['subscription_id'], true, $subscription); ?> </td> <td> <?php if (!$subscription['days'] && !$subscription['months'] && !$subscription['years']) { echo _l('Once off'); } else { $bits = array(); if ($subscription['days'] > 0) { $bits[] = _l('%s days', $subscription['days']); } if ($subscription['months'] > 0) { $bits[] = _l('%s months', $subscription['months']); }
break; case _INVOICE_PAYMENT_TYPE_CREDIT: _e('Credit from customer %s', module_customer::link_open($invoice_payment_data['other_id'], true)); break; case _INVOICE_PAYMENT_TYPE_DEPOSIT: _e('Deposit from invoice %s', module_invoice::link_open($invoice_payment_data['other_id'], true)); break; case _INVOICE_PAYMENT_TYPE_OVERPAYMENT_CREDIT: _e('Assigning Credit to: %s', module_customer::link_open($invoice['customer_id'], true)); break; case _INVOICE_PAYMENT_TYPE_REFUND: _e('Refund: %s', htmlspecialchars($invoice_payment_data['method'])); break; case _INVOICE_PAYMENT_TYPE_SUBSCRIPTION_CREDIT: $subscription_owner = module_subscription::get_subscription_owner($invoice_payment_data['other_id']); _e('Subscription credit from %s', module_subscription::link_open($subscription_owner['subscription_id'], true)); break; } ?> </td> <td> <span class="currency"> <?php /* echo $invoice_payment_data['amount']>0 ? dollar($invoice_payment_data['amount'],true,$invoice['currency_id']) : dollar($invoice_payment_data['hours']*$invoice['hourly_rate'],true,$invoice['currency_id']); */ ?> <?php echo dollar($invoice_payment_data['amount'], true, $invoice_payment_data['currency_id']); // is there a fee? if ($invoice_payment_data['fee_total'] != 0) {
public static function get_finance_recurring_items($hook, $search) { /** * next_due_date * url * type (i or e) * amount * currency_id * days * months * years * last_transaction_finance_id * account_name * categories * finance_recurring_id */ // find any unpaid invoices. $invoices = self::get_invoices(array('date_paid' => '0000-00-00')); $return = array(); foreach ($invoices as $invoice) { // filter out invoices that haven't been sent yet? probably should... //$invoice = self::get_invoice($invoice['invoice_id']); if (isset($invoice['date_cancel']) && $invoice['date_cancel'] != '0000-00-00') { continue; } // check if this invoice is part of a subscription, put in some additional info for this subscriptions // 'recurring_text' if ($invoice['member_id']) { $member_name = module_member::link_open($invoice['member_id'], true); } else { if ($invoice['customer_id']) { $member_name = module_customer::link_open($invoice['customer_id'], true); } else { $member_name = _l('N/A'); } } $recurring_text = _l('Payment from %s', $member_name); if (class_exists('module_subscription', false) && isset($invoice['invoice_subscription_ids'])) { $sql = "SELECT sh.*, s.name FROM `" . _DB_PREFIX . "subscription_history` sh LEFT JOIN `" . _DB_PREFIX . "subscription` s USING (subscription_id) WHERE sh.invoice_id = " . (int) $invoice['invoice_id'] . ""; $res = qa1($sql); if ($res) { $subscription_name = module_subscription::link_open($res['subscription_id'], true, $res); $recurring_text = _l('Payment from %s on subscription %s', $member_name, $subscription_name); } } if (!isset($invoice['c_total_amount_due'])) { $invoice = module_invoice::get_invoice($invoice['invoice_id']); $invoice['c_total_amount_due'] = $invoice['total_amount_due']; } $return[$invoice['invoice_id']] = array('next_due_date' => $invoice['date_due'] && $invoice['date_due'] != '0000-00-00' ? $invoice['date_due'] : $invoice['date_created'], 'url' => module_invoice::link_open($invoice['invoice_id'], true, $invoice), 'type' => 'i', 'amount' => $invoice['c_total_amount_due'], 'currency_id' => $invoice['currency_id'], 'days' => 0, 'months' => 0, 'years' => 0, 'last_transaction_finance_id' => 0, 'account_name' => '', 'categories' => '', 'finance_recurring_id' => 0, 'recurring_text' => $recurring_text); } // find any automatically renewing invoices. $invoices = self::get_invoices(array('renewing' => 1)); foreach ($invoices as $invoice) { // filter out invoices that haven't been sent yet? probably should... //$invoice = self::get_invoice($invoice['invoice_id']); if (isset($invoice['date_cancel']) && $invoice['date_cancel'] != '0000-00-00') { continue; } // check if this invoice is part of a subscription, put in some additional info for this subscriptions // 'recurring_text' if ($invoice['member_id']) { $member_name = module_member::link_open($invoice['member_id'], true); } else { if ($invoice['customer_id']) { $member_name = module_customer::link_open($invoice['customer_id'], true); } else { $member_name = _l('N/A'); } } if ($invoice['renew_auto']) { $recurring_text = _l('Automatically Renewing invoice for %s', $member_name); } else { $recurring_text = _l('Manually Renewing invoice for %s', $member_name); } if (!isset($invoice['c_total_amount'])) { $invoice = module_invoice::get_invoice($invoice['invoice_id']); $invoice['c_total_amount'] = $invoice['total_amount']; } $return[] = array('next_due_date' => date('Y-m-d', strtotime('+' . module_config::c('invoice_due_days', 30) . ' days', strtotime($invoice['date_renew']))), 'url' => module_invoice::link_open($invoice['invoice_id'], true, $invoice), 'type' => 'i', 'amount' => $invoice['c_total_amount'], 'currency_id' => $invoice['currency_id'], 'days' => 0, 'months' => 0, 'years' => 0, 'last_transaction_finance_id' => 0, 'account_name' => '', 'categories' => '', 'finance_recurring_id' => 0, 'recurring_text' => $recurring_text); } return $return; }
public static function run_cron($debug = false) { // we only want to perform these cron actions if we're after a certain time of day // because we dont want to be generating these renewals and sending them at midnight, can get confusing $after_time = module_config::c('invoice_automatic_after_time', 7); $time_of_day = date('G'); if ($time_of_day < $after_time) { if ($debug) { echo "Not performing automatic subscription operations until after {$after_time}:00 - it is currently {$time_of_day}:" . date('i') . "<br>\n"; } return; } // find all automatic subscriptions and renew them (if applicable) $sql = "SELECT * FROM `" . _DB_PREFIX . "subscription` s "; $sql .= " WHERE s.automatic_renew = 1"; $subscriptions = qa($sql); foreach ($subscriptions as $subscription) { if ($subscription['automatic_renew']) { if ($debug) { echo "<br>\nProcessing subscription renewals for subscription " . module_subscription::link_open($subscription['subscription_id'], true) . "<br>\n<br>\n"; } // find all the members/customers from this subscription //$members = module_subscription::get_subscribed_members($subscription['subscription_id']); //$customers = module_subscription::get_subscribed_customers($subscription['subscription_id']); $owners = module_subscription::get_subscribed_owners($subscription['subscription_id']); foreach ($owners as $member) { if (!$member['next_generation_date'] || $member['next_generation_date'] == '0000-00-00') { continue; } if (!$member['next_due_date'] || $member['next_due_date'] == '0000-00-00') { continue; } if ($debug) { echo "Doing: " . $member['owner_table'] . " " . $member['owner_id'] . "<br>\n"; } // check permissions for logged in users, dont want the cron to run when someone is logged in and no access to this account. if (module_security::is_logged_in()) { switch ($member['owner_table']) { case 'website': $website_perm_check = module_website::get_website($member['owner_id']); if (!$website_perm_check || $website_perm_check['website_id'] != $member['owner_id']) { continue 2; } if ($debug) { echo "permission pass for website: " . $website_perm_check['website_id']; } break; case 'customer': $customer_perm_check = module_customer::get_customer($member['owner_id']); if (!$customer_perm_check || $customer_perm_check['customer_id'] != $member['owner_id']) { continue 2; } if ($debug) { echo "permission pass for customer: " . $customer_perm_check['customer_id']; } break; } } // is the last invoice unpaid? $history = self::get_subscription_history($subscription['subscription_id'], $member['owner_table'], $member['owner_id']); $next_due_time_invoice_created = false; $invoice_unpaid = false; if (isset($member['recur_limit']) && (int) $member['recur_limit'] > 0 && count($history) >= (int) $member['recur_limit']) { if ($debug) { echo " - not renewing this one because it has hit our recur limit of " . $member['recur_limit'] . "<br>\n"; } continue; } foreach ($history as $h) { $last_invoice = module_invoice::get_invoice($h['invoice_id']); if (!$last_invoice || $last_invoice['date_cancel'] != '0000-00-00') { continue; } // check the new 'next_due_date' entry in the db table if (isset($h['from_next_due_date']) && $h['from_next_due_date'] && $h['from_next_due_date'] != '0000-00-00') { // we're using the new method of checking when an invoice was generated, rather than the confusing invoice 'date_create' check below if ($debug) { echo " - checking if next_due_date " . print_date($member['next_due_date']) . " matches subscription history from_next_due_date for invoice " . module_invoice::link_open($h['invoice_id'], true, $last_invoice) . " from_next_due_date: " . print_date($h['from_next_due_date']) . " (invoice create_date: " . print_date($last_invoice['date_create']) . ")<br>\n"; } if (print_date($member['next_due_date']) == print_date($h['from_next_due_date'])) { //print_date($last_invoice['date_create'])){ // this invoice is for the next due date. $next_due_time_invoice_created = $last_invoice; } } else { if ($debug) { echo " - checking if next_generation_date (" . print_date($member['next_generation_date']) . ") or next_due_date (" . print_date($member['next_due_date']) . ") matches invoice " . module_invoice::link_open($h['invoice_id'], true, $last_invoice) . " created date (" . print_date($last_invoice['date_create']) . ") <br>\n"; } if (print_date($member['next_generation_date']) == print_date($last_invoice['date_create']) || print_date($member['next_due_date']) == print_date($last_invoice['date_create'])) { //print_date($last_invoice['date_create'])){ // this invoice is for the next due date. $next_due_time_invoice_created = $last_invoice; } } if ($last_invoice['total_amount_due'] > 0) { $invoice_unpaid = true; } } //self::generate_subscription_invoice($subscription_id, $customer_hack, $member_id, $date, $amount) $next_due_time = strtotime($member['next_generation_date']); if ($debug) { echo " - next subscription time is " . $member['next_generation_date'] . " <br>\n"; } if ($next_due_time <= strtotime(date('Y-m-d')) && !$next_due_time_invoice_created) { if ($debug) { echo " - Yes its time to generate an invoice!<br>\n"; } if (module_config::c('invoice_auto_renew_only_paid_invoices', 1) && $invoice_unpaid) { if ($debug) { echo " - skipping generating renewal for " . $member['owner_table'] . " " . $member['owner_id'] . " because a previous subscription is unpaid <br>\n"; } continue; } // time to generate! woo! if ($debug) { echo " - generating subscription renewal for " . $member['owner_table'] . " " . $member['owner_id'] . "<br>\n"; } $invoice_id = self::generate_subscription_invoice($subscription['subscription_id'], $member['owner_table'], $member['owner_id'], $member['next_generation_date'], $subscription['amount']); if ($debug) { echo " - generated invoice " . module_invoice::link_open($invoice_id, true) . " for subscription <br>\n"; } if ($subscription['automatic_email']) { if ($debug) { echo " - emailing invoice to " . $member['owner_table'] . "... <br>\n"; } if (module_invoice::email_invoice_to_customer($invoice_id, $debug)) { if ($debug) { echo "send successfully <br>\n"; } } else { echo " - failed to send invoice " . module_invoice::link_open($invoice_id, true) . " to " . $member['owner_table'] . " <br>\n"; } } } else { if ($debug) { echo " - skipping generating renewal for " . $member['owner_table'] . " " . $member['owner_id'] . " because the due date has already been generated <br>\n"; } } } } } }
$c = 0; $total_total = array(0, 0); $total_received = array(0, 0); $total_unpaid = array(0, 0); $total_members = 0; $total_customers = 0; foreach ($subscription_reports as $subscription_report) { ?> <tr class="<?php echo $c++ % 2 ? "odd" : "even"; ?> "> <td> <?php echo module_subscription::link_open($subscription_report['subscription_id'], true, $subscription_report); ?> </td> <td> <?php $total_total[0] += $subscription_report['total_received_count'] + $subscription_report['total_unpaid_count']; $total_total[1] += $subscription_report['total_received'] + $subscription_report['total_unpaid']; // todo - multicurrency echo $subscription_report['total_received_count'] + $subscription_report['total_unpaid_count']; ?> = <?php echo dollar($subscription_report['total_received'] + $subscription_report['total_unpaid'], true, $subscription_report['currency_id']); ?>
if (count($subscription_owner)) { ob_start(); ?> <table border="0" cellspacing="0" cellpadding="2" class="tableclass tableclass_form tableclass_full"> <tbody> <tr> <td> <?php switch ($subscription_owner['owner_table']) { case 'member': $member_name = module_member::link_open($subscription_owner['owner_id'], true); break; case 'website': $member_name = module_website::link_open($subscription_owner['owner_id'], true); break; case 'customer': $member_name = module_customer::link_open($subscription_owner['owner_id'], true); break; } $subscription_name = module_subscription::link_open($subscription['subscription_id'], true); _e('This is a subscription payment for %s %s on the subscription: %s', $subscription_owner['owner_table'], $member_name, $subscription_name); ?> </td> </tr> </tbody> </table> <?php $fieldset_data = array('heading' => array('title' => _l('%s Subscription', _l(ucwords($subscription_owner['owner_table']))), 'type' => 'h3'), 'elements_before' => ob_get_clean()); echo module_form::generate_fieldset($fieldset_data); } }