<?php
require_once 'modules/admin/models/ServicePlugin.php';
require_once 'modules/billing/models/BillingType.php';
require_once 'modules/billing/models/Invoice_EventLog.php';

/**
* @package Plugins
*/
class PluginInvoicegenerator extends ServicePlugin
{
    function getVariables()
    {
        $variables = array(
            /*T*/'Plugin Name'/*/T*/   => array(
                'type'          => 'hidden',
                'description'   => /*T*/''/*/T*/,
                'value'         => /*T*/'Invoice Generator'/*/T*/,
            ),
            /*T*/'Enabled'/*/T*/       => array(
                'type'          => 'yesno',
                'description'   => /*T*/'When enabled, invoices will automatically be sent to your customers for non-autopayment gateways.'/*/T*/,
                'value'         => '0',
            ),
            /*T*/'Run schedule - Minute'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number, range, list or steps'/*/T*/,
                'value'         => '30',
                'helpid'        => '8',
            ),
            /*T*/'Run schedule - Hour'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number, range, list or steps'/*/T*/,
                'value'         => '*',
            ),
            /*T*/'Run schedule - Day'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number, range, list or steps'/*/T*/,
                'value'         => '*',
            ),
            /*T*/'Run schedule - Month'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number, range, list or steps'/*/T*/,
                'value'         => '*',
            ),
            /*T*/'Run schedule - Day of the week'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number in range 0-6 (0 is Sunday) or a 3 letter shortcut (e.g. sun)'/*/T*/,
                'value'         => '*',
            ),
        );
    
        return $variables;
    }
    
    function execute()
    {
        $messages = array();
        $numCustomers = 0;
        require_once 'modules/billing/models/BillingGateway.php';
        
        $query = "SELECT DISTINCT (c.id), c.paymenttype, c.autopayment "
                ."FROM users c, recurringfee r "

                ."LEFT JOIN domains d ON r.appliestoid = d.id "

                ."WHERE c.groupid = 1 "
                ."AND c.autopayment = 0 "
                ."AND c.status = 1 "
                ."AND r.disablegenerate <> 2 "
                ."AND r.customerid = c.id "

                //."AND r.status = 1 "
                ."AND (r.appliestoid = 0 "
                ."OR (r.appliestoid <> 0 "
                ."AND d.status IN (".PACKAGE_STATUS_PENDING.", ".PACKAGE_STATUS_ACTIVE.") "
                ."AND (r.billingtypeid <> ".BILLINGTYPE_PACKAGE." "
                ."OR (r.billingtypeid = ".BILLINGTYPE_PACKAGE." "
                ."AND r.recurring = 1)))) "

                ."AND (TO_DAYS(r.nextbilldate) - TO_DAYS(NOW()) <=".$this->settings->get('Send Invoice Offset').")";
        $result = $this->db->query($query);
        while(list($customerid,$paymenttype,$userautopayment) = $result->fetch()) {
            $billingGateway = new BillingGateway($this->user);
            $returnArray = $billingGateway->processCustomerBilling($customerid, $userautopayment);
            
            if (!isset($returnArray['invoiceIDs'])) {
                $returnArray['invoiceIDs'] = array();
            }
            
            if ($returnArray["bolBillableItem"]) {
                foreach ($returnArray["invoiceIDs"] as $tInvoiceID) {
                    try {
                        $invoiceLog = Invoice_EventLog::newInstance($customerid, $tInvoiceID, INVOICE_EVENTLOG_CREATED, $this->user->getId());
                        $this->logger->addEventLog($invoiceLog);
                        
                        $invoicesData = $billingGateway->processApplyAccountCredits($tInvoiceID);
                        
                        if(isset($invoicesData[trim($tInvoiceID)])){
                            $invoiceLog = Invoice_EventLog::newInstance($invoicesData[trim($tInvoiceID)]['userID'], trim($tInvoiceID), INVOICE_EVENTLOG_APPLY_ACCOUNT_CREDIT, $this->user->getId(), serialize($invoicesData[trim($tInvoiceID)]));
                            $this->logger->addEventLog($invoiceLog);
                            
                            if($invoicesData[trim($tInvoiceID)]['status'] == "Fully"){
                                $billingGateway->sendPaymentEmail($tInvoiceID, true);
                            }
                        }
                    }catch(Exception $ex) {
                        $this->logger->log(1, $ex);
                    }
                }
            }
            
            $numCustomers++;
        }

        $this->settings->updateSetting("LastDateGenerateInvoices", mktime());

        array_unshift($messages, "$numCustomers customer(s) were invoiced");
        return $messages;
    }

    /*
    To show the prices for the pendingItems it is almost to do all the process required to generate the invoices.
    We have many things to take in count like if domain or package prices, if override, if univoiced items tied to next invoices, taxes, etc.
    It is basically doing all what the functions processCustomerBilling, generateOutstandingBillableWork and _addNonRecurringCharges from BillingGateway class,
    and recalculateInvoice from Invoice class do, but requiring to not generate anything in the database.
    That is really something useless.
    */
    function pendingItems()
    {
        include_once 'modules/clients/models/user.php';
        
        $returnArray = array();
        $returnArray['data'] = array();
        // Select all customers that have an invoice that needs generation
        $query = "SELECT DISTINCT c.id, UNIX_TIMESTAMP(r.nextbilldate) "
            ."FROM users c, recurringfee r "
            
            ."LEFT JOIN domains d ON r.appliestoid = d.id "
            
            ."WHERE c.groupid = 1 "
            ."AND c.autopayment = 0 "
            ."AND c.status = 1 "
            ."AND r.disablegenerate <> 2 "
            ."AND r.customerid = c.id "
            
            //."AND r.status = 1 "
            ."AND (r.appliestoid = 0 "
            ."OR (r.appliestoid <> 0 "
            ."AND d.status IN (".PACKAGE_STATUS_PENDING.", ".PACKAGE_STATUS_ACTIVE.") "
            ."AND (r.billingtypeid <> ".BILLINGTYPE_PACKAGE." "
            ."OR (r.billingtypeid = ".BILLINGTYPE_PACKAGE." "
            ."AND r.recurring = 1)))) "
            
            ."AND (TO_DAYS(r.nextbilldate) - TO_DAYS(NOW()) <=".$this->settings->get('Send Invoice Offset').") "
            ."ORDER BY UNIX_TIMESTAMP(r.nextbilldate) ASC";
        $result = $this->db->query($query);
        
        // Loop through the customers
        while ($row = $result->fetch()) {
            $user = new User($row['id']);
            
            $tmpInfo = array();
            $tmpInfo['customerid'] = $row['id'];
            $tmpInfo['customer'] = $user->getFullName();
            $tmpInfo['due'] = date($this->settings->get('Date Format'),$row['UNIX_TIMESTAMP(r.nextbilldate)']);
            $returnArray['data'][] = $tmpInfo;
        }
        
        $returnArray['totalcount'] = count($returnArray['data']);
        return $returnArray;
    }

    function output() { }
    
    function dashboard()
    {
        $query = "SELECT COUNT(DISTINCT (c.id))  AS customers "
                ."FROM users c, recurringfee r "

                ."LEFT JOIN domains d ON r.appliestoid = d.id "

                ."WHERE c.groupid = 1 "
                ."AND c.autopayment = 0 "
                ."AND c.status = 1 "
                ."AND r.disablegenerate <> 2 "
                ."AND r.customerid = c.id "

                //."AND r.status = 1 "
                ."AND (r.appliestoid = 0 "
                ."OR (r.appliestoid <> 0 "
                ."AND d.status IN (".PACKAGE_STATUS_PENDING.", ".PACKAGE_STATUS_ACTIVE.") "
                ."AND (r.billingtypeid <> ".BILLINGTYPE_PACKAGE." "
                ."OR (r.billingtypeid = ".BILLINGTYPE_PACKAGE." "
                ."AND r.recurring = 1)))) "

                ."AND (TO_DAYS(r.nextbilldate) - TO_DAYS(NOW()) <=".$this->settings->get('Send Invoice Offset').")";
        $result = $this->db->query($query);
        $row = $result->fetch();
        if (!$row) {
            $row['customers'] = 0;
        }
        return $this->user->lang('Number of customers to be billed: %d', $row['customers']);
    }
}
?>