WIP Setup billing tab
authorSteve Sutton <steve@gaslightmedia.com>
Wed, 22 Nov 2017 19:38:16 +0000 (14:38 -0500)
committerSteve Sutton <steve@gaslightmedia.com>
Wed, 22 Nov 2017 19:38:16 +0000 (14:38 -0500)
Setting up dashboard and list invoice pages for the billing.

models/admin/billing/index.php [new file with mode: 0644]
models/admin/billing/invoices.php [new file with mode: 0644]
setup/adminMenus.php
setup/adminTabs.php
setup/validActions.php
views/admin/billing/header.html [new file with mode: 0644]
views/admin/billing/index.html [new file with mode: 0644]

diff --git a/models/admin/billing/index.php b/models/admin/billing/index.php
new file mode 100644 (file)
index 0000000..b9e3ca1
--- /dev/null
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * Admin Billing Dashboard
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  index.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+// Load Billing data abstract
+// require_once GLM_MEMBERS_BILLING_PLUGIN_CLASS_PATH.'/data/dataBilling.php';
+
+class GlmMembersAdmin_billing_index // extends GlmDataBilling
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+    /**
+     * Plugin Configuration Data
+     *
+     * @var $config
+     * @access public
+     */
+    public $config;
+    /**
+     * Billing ID
+     *
+     * @var $billingID
+     * @access public
+     */
+    public $billingID = false;
+
+    /**
+     * Constructor
+     *
+     * This contructor performs the work for this model. This model returns
+     * an array containing the following.
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     * @wpdb object WordPress database object
+     *
+     * @return array Array containing status, suggested view, and any data
+     */
+    public function __construct ($wpdb, $config)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Save plugin configuration object
+        $this->config = $config;
+
+        /*
+         * Run constructor for the Billing data class
+         *
+         * Note, the third parameter is a flag that indicates to the Contacts
+         * data class that it should flag a group of fields as 'view_only'.
+         */
+        // parent::__construct(false, false, true);
+
+    }
+
+    public function modelAction($actionData = false)
+    {
+
+        $numbPending    = 0;
+        $namesList      = false;
+        $haveCategories = false;
+
+        // For lockedToMember
+        $lockedToMember = false;
+        $lockedWhereT   = 'true';
+        $lockedWhere    = 'true';
+
+        // Check if there's a logged in user who is locked to their own entity
+        $lockedToMember = apply_filters('glm_members_locked_to_member_id', false);
+        if ($lockedToMember) {
+            $memberID = $lockedToMember;
+            $lockedToMember = $memberID;
+            $lockedWhereT = 'T.ref_type = '.$this->config['ref_type_numb']['Member'].' AND T.ref_dest = '.$memberID;
+            $lockedWhere = 'ref_type = '.$this->config['ref_type_numb']['Member'].' AND ref_dest = '.$memberID;
+        }
+
+        // Get number of billing
+        // $numberPending = $this->getStats($lockedWhere.' status = '.$this->config['status_numb']['Pending']);
+
+        // I know this is awkward, but we if there's anything that follows these we need " AND " appended.
+        if ($lockedWhereT != '') {
+            $lockedWhereT .= ' AND ';
+        }
+        if ($lockedWhere != '') {
+            $lockedWhere .= ' AND ';
+        }
+
+        // Compile template data
+        $templateData = array(
+            'lockedToMember' => $lockedToMember,
+            'numberPending'  => $numberPending,
+        );
+             // Return status, any suggested view, and any data to controller
+        return array(
+            'status'        => true,
+            'modelRedirect' => false,
+            'view'          => 'admin/billing/index.html',
+            'data'          => $templateData
+        );
+
+    }
+
+
+}
diff --git a/models/admin/billing/invoices.php b/models/admin/billing/invoices.php
new file mode 100644 (file)
index 0000000..6a7a6d5
--- /dev/null
@@ -0,0 +1,494 @@
+<?php
+/**
+ * Gaslight Media Members Database
+ * Admin Transactions List
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmMembersDatabase
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  index.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+// Load Contacts data class
+// require_once GLM_MEMBERS_TRANSACTIONS_PLUGIN_CLASS_PATH.'/data/dataTransactions.php';
+
+class GlmMembersAdmin_billing_list // extends GlmDataTransactions
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+    /**
+     * Plugin Configuration Data
+     *
+     * @var $config
+     * @access public
+     */
+    public $config;
+    /**
+     * Transactions ID
+     *
+     * @var $transactionID
+     * @access public
+     */
+    public $transactionID = false;
+
+    /**
+     * Constructor
+     *
+     * This contructor performs the work for this model. This model returns
+     * an array containing the following.
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     * @wpdb object WordPress database object
+     *
+     * @return array Array containing status, suggested view, and any data
+     */
+    public function __construct ($wpdb, $config)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Save plugin configuration object
+        $this->config = $config;
+
+        /*
+         * Run constructor for the Contacts data class
+         *
+         * Note, the third parameter is a flag that indicates to the Contacts
+         * data class that it should flag a group of fields as 'view_only'.
+         */
+        // parent::__construct(false, false, true);
+
+    }
+
+    public function modelAction($actionData = false)
+    {
+
+        $currentTab              = 'glm-table-descr';
+        $lockedToMember          = false;
+        $isModerated             = false;
+        $numbTransactions        = 0;
+        $option                  = 'list';
+        $transactions            = false;
+        $haveTransactions        = false;
+        $transactions            = false;
+        $haveTransactions        = false;
+        $this->transactionID    = false;
+        $transactionsUpdated     = false;
+        $transactionsUpdateError = false;
+        $transactionsAdded       = false;
+        $transactionsAddError    = false;
+        $view                    = 'list';
+        $fromDate                = false;
+        $toDate                  = false;
+        $filterArchived          = false;
+        $filterPending           = false;
+        $filterFeatured          = false;
+        $transactionsDeleted     = false;
+        $transactionsDeleteError = false;
+        $memberID                = false;
+        $haveMember              = false;
+        $memberName              = false;
+        $memberData              = false;
+        $numbDisplayed           = false;
+        $lastDisplayed           = false;
+        $paging                  = true;
+        $prevStart               = false;
+        $nextStart               = false;
+        $start                   = 1;
+        $limit                   = 20;        // Set to the number of listings per page
+        $namesList               = false;
+
+        // Check if there's a logged in user who is locked to their own entity
+        $lockedToMember = apply_filters('glm_members_locked_to_member_id', false);
+        if ($lockedToMember) {
+            $isModerated = apply_filters('glm_user_is_moderated', $lockedToMember);
+            $memberID = $lockedToMember;
+            $this->fields['admin_name']['required']  = true;
+            $this->fields['admin_email']['required'] = true;
+            $this->fields['admin_phone']['required'] = true;
+
+            // Check for Member Menu Use
+        } elseif (defined('GLM_TRANSACTIONS_MEMBER_MENU')) {
+
+            // Try to get member ID
+            $memberID = (isset($_REQUEST['member']) ? $_REQUEST['member'] : 0);
+
+            // If there's no valid member ID, we can't continue
+            if ($memberID == 0) {
+                return array(
+                    'status'           => false,
+                    'menuItemRedirect' => 'error',
+                    'modelRedirect'    => 'index',
+                    'view'             => 'admin/error/index.html',
+                    'data'             => array(
+                        'reason' => 'No member ID was provided.'
+                    )
+                );
+            }
+        }
+
+        // If not a valid member ID
+        if ($memberID > 0) {
+
+            // Get base member information
+            require_once GLM_MEMBERS_PLUGIN_CLASS_PATH.'/data/dataMembers.php';
+            $Member     = new GlmDataMembers($this->wpdb, $this->config);
+            $memberData = $Member->getEntry($memberID);
+
+            if (!$memberData) {
+                return array(
+                    'status'           => false,
+                    'menuItemRedirect' => 'error',
+                    'modelRedirect'    => 'index',
+                    'view'             => 'admin/error/index.html',
+                    'data'             => array(
+                        'reason' => 'No member data found for provided member ID.'
+                    )
+                );
+            } else{
+                $haveMember = true;
+                $memberName = $memberData['name'];
+            }
+
+        }
+
+        // Get any provided option
+        if (isset($_REQUEST['option'])) {
+            $option = $_REQUEST['option'];
+        }
+
+        // See if there's a currentTab in $_REQUEST array
+        if ( isset( $_REQUEST['currentTab'] ) && $_REQUEST['currentTab'] ) {
+            $currentTab = filter_var( $_REQUEST['currentTab'], FILTER_SANITIZE_STRING );
+        }
+
+        // Get transactions ID if supplied
+        if (isset($_REQUEST['transactions'])) {
+
+            // Make sure it's numeric
+            $this->transactionID = ($_REQUEST['transactions'] - 0);
+
+            if ($this->transactionID <= 0) {
+                $this->transactionID = false;
+            }
+
+        }
+
+        // Do selected option
+        switch ($option) {
+
+        case 'add':
+            $transactions = $this->newEntry();
+            $view = 'edit';
+            break;
+
+        case 'insert':
+            $transactions = $this->insertEntry();
+            $this->transactionID = $transactions['fieldData']['id'];
+            $view = 'edit';
+            break;
+
+        case 'edit':
+            $transactions = $this->editEntry($this->transactionID);
+
+            // If we have a good transactions
+            if ($transactions['status']) {
+                $haveTransactions = true;
+            }
+
+            // If we're locked to a member as a contact user and the transactions member doesn't equal the contact member
+            if ($lockedToMember && $transactions['fieldData']['ref_dest_id'] != $lockedToMember) {
+                $haveTransactions = false;
+                $transactions = false;
+            }
+
+            $view = 'edit';
+            break;
+
+        case 'update':
+
+            // Try to update this transactions
+            $transactions = $this->updateEntry($this->transactionID);
+
+            // Check if that was successful
+            if ($transactions['status']) {
+                $transactionsUpdated = true;
+
+                $transactions = $this->editEntry($this->transactionID);
+            } else {
+                $transactionsUpdateError = true;
+            }
+
+            $view = 'edit';
+
+            break;
+
+        case 'delete':
+
+            $transactions = $this->deleteTransactions($this->transactionID);
+
+            if ($transactions) {
+                $transactionsDeleted = true;
+            } else {
+                $transactionsDeleteError = true;
+            }
+
+            case 'list':
+        default:
+
+            $where = 'true';
+
+            // If we have a back request then go through the PHP_SESSION
+            // and extract them into the REQUEST array.
+            if ( isset( $_REQUEST['back'] ) && filter_var( $_REQUEST['back'], FILTER_VALIDATE_BOOLEAN ) ) {
+                if ( isset( $_SESSION['search'] ) && is_array( $_SESSION['search'] ) ) {
+                    foreach ( $_SESSION['search'] as $varName => $sessValue ) {
+                        $_REQUEST[$varName] = $sessValue;
+                    }
+                }
+            }
+
+            // Check for paging
+            if ( isset( $_REQUEST['pageSelect'] ) ) {
+                $_SESSION['search']['pageSelect'] = $_REQUEST['pageSelect'];
+            } else if ( isset( $_REQUEST['searched'] ) && !isset( $_REQUEST['pageSelect'] ) ) {
+                unset( $_SESSION['search']['pageSelect'] );
+            }
+            if ( isset( $_REQUEST['nextStart'] ) ) {
+                $_SESSION['search']['nextStart'] = $_REQUEST['nextStart'];
+            } else if ( isset( $_REQUEST['searched'] ) && !isset( $_REQUEST['nextStart'] ) ) {
+                unset( $_SESSION['search']['nextStart'] );
+            }
+            if ( isset( $_REQUEST['prevStart'] ) ) {
+                $_SESSION['search']['prevStart'] = $_REQUEST['prevStart'];
+            } else if ( isset( $_REQUEST['searched'] ) && !isset( $_REQUEST['prevStart'] ) ) {
+                unset( $_SESSION['search']['prevStart'] );
+            }
+
+            // Check for Archived filter
+            if (isset($_REQUEST['filterArchived']) && $_REQUEST['filterArchived'] == 'on') {
+                $filterArchived = true;
+                $_SESSION['search']['archived'] = true;
+                $where .= " AND status = " . $this->config['status_numb']['Archived'];
+            } else if ( isset( $_REQUEST['searched'] ) && !isset( $_REQUEST['filterArchived'] ) ) {
+                unset( $_SESSION['search']['archived'] );
+            }
+
+            // Check for Pending filter
+            if (isset($_REQUEST['filterPending']) && $_REQUEST['filterPending'] == 'on') {
+                $filterPending = true;
+                $_SESSION['search']['pending'] = true;
+                $where .= " AND status = " . $this->config['status_numb']['Pending'];
+            } else if ( isset( $_REQUEST['searched'] ) && !isset( $_REQUEST['filterPending'] ) ) {
+                unset( $_SESSION['search']['pending'] );
+            }
+
+            // Check if we have a Text Search string
+            if (isset($_REQUEST['textSearch']) && trim($_REQUEST['textSearch']) != '') {
+                $textSearch = trim($_REQUEST['textSearch']);
+                $where .= " AND name LIKE '%$textSearch%'";
+                $_SESSION['search']['textSearch'] = $textSearch;
+            } else if ( isset( $_REQUEST['searched'] ) && trim($_REQUEST['textSearch']) == '' ) {
+                unset( $_SESSION['search']['textSearch'] );
+            }
+
+
+            // If we have a From date
+            $dateWhere = '';
+            if (isset($_REQUEST['fromDate']) && trim($_REQUEST['fromDate']) != '') {
+                $fromDate = date('m/d/Y', strtotime($_REQUEST['fromDate']));
+                $fromMYSQL = date('Y-m-d', strtotime($fromDate));
+                $dateWhere = " end_time >= '$fromMYSQL' ";
+                $_SESSION['search']['fromDate'] = $fromDate;
+            } else if ( !isset( $_REQUEST['searched'] ) ) {
+                $fromDate = date('m/d/Y');
+                $fromMYSQL = date('Y-m-d', strtotime($fromDate));
+                $dateWhere = " end_time >= '$fromMYSQL' ";
+            } else if ( isset( $_REQUEST['searched'] ) && trim($_REQUEST['fromDate']) == '' ) {
+                unset( $_SESSION['search']['fromDate'] );
+            }
+
+            // If we have a to Date
+            if (isset($_REQUEST['toDate']) && trim($_REQUEST['toDate']) != '') {
+
+                $toDate = date('m/d/Y', strtotime($_REQUEST['toDate']));
+                $toMYSQL = date('Y-m-d', strtotime($toDate." +1 day"));
+
+                // If we have a from date then we need Parens and AND
+                if ($dateWhere != '') {
+                    $dateWhere = "( ".$dateWhere." AND start_time <= '$toMYSQL' )";
+
+                // Otherwise we don't
+                } else {
+                    $dateWhere = " start_time <= '$toMYSQL' ";
+                }
+                $_SESSION['search']['toDate'] = $toDate;
+            } else if ( isset( $_REQUEST['searched'] ) && trim($_REQUEST['toDate']) == '' ) {
+                unset( $_SESSION['search']['toDate'] );
+            }
+
+            // If we have from and to dates, do search for those inclusive
+            if ($dateWhere != '') {
+                $where .= "
+                    AND id in (
+                        SELECT DISTINCT(transactions)
+                          FROM ".GLM_MEMBERS_TRANSACTIONS_PLUGIN_DB_PREFIX."times
+                         WHERE $dateWhere
+                           AND active
+                    )
+                ";
+            }
+
+            // Check if the list is for a specific member
+            if (defined('GLM_TRANSACTIONS_MEMBER_MENU') || $memberID) {
+                $where .= " AND ref_dest = $memberID";
+                $_SESSION['search']['memberID'] = $memberID;
+            }
+
+            // Get the total number of transactions listed
+            $numbTransactions = $this->getStats($where);
+
+            // If the number of transactions is less than a page, don't do paging
+            if ($numbTransactions <= $limit) {
+                $paging = false;
+            }
+
+            // Get full list of names matching this where clause for search box
+            $namesList = $this->getIdName($where);
+
+            // Check if we're doing paging
+            if (isset($_REQUEST['pageSelect'])) {
+                // If request is for Next
+                if ($_REQUEST['pageSelect'][0] == 'N') {
+                    $newStart = $_REQUEST['nextStart'] - 0;
+
+                // Otherwise it must be Previous
+                } else {
+                    $newStart = $_REQUEST['prevStart'] - 0;
+                }
+
+                if ($newStart > 0) {
+                    $start = $newStart;
+                }
+            }
+
+            if( isset($_SESSION['search']['pageSelect']) ){
+                 // If request is for Next
+                if ($_SESSION['search']['pageSelect'][0] == 'N') {
+                    $newStart = $_SESSION['search']['nextStart'] - 0;
+
+                // Otherwise it must be Previous
+                } else {
+                    $newStart = $_SESSION['search']['prevStart'] - 0;
+                }
+                if ($newStart > 0) {
+                    $start = $newStart;
+                }
+            }
+
+            // Get the list of transactions and determine number of transactions in list
+            $orderBy = 'name';
+            // $orderBy = "(select min(start_time) FROM " . GLM_MEMBERS_BILLING_PLUGIN_DB_PREFIX . "times WHERE T.id = transactions),name";
+            $transactionsResult = $this->getList($where, $orderBy, true, 'id', $start, $limit);
+
+            // Get paging results
+            $numbDisplayed = $transactionsResult['returned'];
+            $lastDisplayed = $transactionsResult['last'];
+            if ($start == 1) {
+                $prevStart = false;
+            } else {
+                $prevStart = $start - $limit;
+                if ($start < 1) {
+                    $start = 1;
+                }
+            }
+            if ($transactionsResult['returned'] == $limit) {
+                $nextStart = $start + $limit;
+            }
+
+            // since we're doing paging, we have to break out just the transactions data
+            $transactions = $transactionsResult['list'];
+            if (count($transactions)>0) {
+                $haveTransactions = true;
+            }
+            unset($transactionsResult);
+
+            break;
+
+        }
+
+        $templateData = array(
+            'enable_members'          => $enable_members,
+            'lockedToMember'          => $lockedToMember,
+            'isModerated'             => $isModerated,
+            'option'                  => $option,
+            'transactions'            => $transactions,
+            'haveTransactions'        => $haveTransactions,
+            'transactions'            => $transactions,
+            'haveTransactions'        => $haveTransactions,
+            'transactionID'           => $this->transactionID,
+            'transactionsUpdated'     => $transactionsUpdated,
+            'transactionsUpdateError' => $transactionsUpdateError,
+            'transactionsAdded'       => $transactionsAdded,
+            'transactionsAddError'    => $transactionsAddError,
+            'numbTransactions'        => $numbTransactions,
+            'categories'              => $categories,
+            'amenities'               => $amenities,
+            'fromDate'                => $fromDate,
+            'toDate'                  => $toDate,
+            'filterArchived'          => $filterArchived,
+            'filterPending'           => $filterPending,
+            'filterFeatured'          => $filterFeatured,
+            'transactionsDeleted'     => $transactionsDeleted,
+            'transactionsDeleteError' => $transactionsDeleteError,
+            'memberID'                => $memberID,
+            'haveMember'              => $haveMember,
+            'memberName'              => $memberName,
+            'memberData'              => $memberData,
+            'numbDisplayed'           => $numbDisplayed,
+            'lastDisplayed'           => $lastDisplayed,
+            'paging'                  => $paging,
+            'prevStart'               => $prevStart,
+            'nextStart'               => $nextStart,
+            'start'                   => $start = 1,
+            'limit'                   => $limit,
+            'namesList'               => $namesList,
+            'currentTab'              => $currentTab
+        );
+
+        // Return status, any suggested view, and any data to controller
+        return array(
+            'status'        => true,
+            'modelRedirect' => false,
+            'view'          => "admin/billing/$view.html",
+            'data'          => $templateData
+        );
+
+    }
+
+}
index 70d9e35..affa099 100644 (file)
  * is named the same as the "glm_action" parameter.
  *
  */
-
+if ( current_user_can( 'glm_members_members' ) ) {
+    add_submenu_page(
+        'glm-members-admin-menu-members',
+        'Billing / Reports',
+        'Billing',
+        'glm_members_members',
+        'glm-members-admin-menu-billing',
+        function() { $this->controller('billing', 'index'); }
+    );
+}
index 9261ce4..6ae2f5d 100644 (file)
@@ -59,4 +59,16 @@ if ( current_user_can( 'glm_members_members' ) ) {
             return $addOnTabs;
         }
     );
+    add_filter( 'glm-member-db-add-tab-for-billing',
+        function( $addOnTabs ){
+            $newTabs = array(
+                array(
+                    'text'   => 'Invoices',
+                    'menu'   => 'billing',
+                    'action' => 'billing',
+                    'option' => 'list',
+                )
+            );
+        }
+    );
 }
index ada37b9..8b27d65 100644 (file)
@@ -63,6 +63,10 @@ $glmMembersBillingAddOnValidActions = array(
             'billing'      => GLM_MEMBERS_BILLING_PLUGIN_SLUG,
             'paymentTypes' => GLM_MEMBERS_BILLING_PLUGIN_SLUG,
         ),
+        'billing' => array(
+            'index' => GLM_MEMBERS_BILLING_PLUGIN_SLUG,
+            'list'  => GLM_MEMBERS_BILLING_PLUGIN_SLUG,
+        ),
     ),
     'frontActions' => array(
     )
diff --git a/views/admin/billing/header.html b/views/admin/billing/header.html
new file mode 100644 (file)
index 0000000..972150b
--- /dev/null
@@ -0,0 +1,9 @@
+<div class="wrap">
+    <h2>Billing</h2>
+    <h2 class="nav-tab-wrapper">
+        <a href="{$thisUrl}?page={$thisPage}&glm_action=index" class="nav-tab{if $thisAction==index} nav-tab-active{/if}">Dashboard</a>
+        <a href="{$thisUrl}?page=glm-members-admin-menu-billing&aoption=list" class="nav-tab{if $thisAction==list} nav-tab-active{/if}">Invoices</a>
+    </h2>
+    <div id="glm-admin-content-container">
+
+
diff --git a/views/admin/billing/index.html b/views/admin/billing/index.html
new file mode 100644 (file)
index 0000000..af2773d
--- /dev/null
@@ -0,0 +1,14 @@
+{include file='admin/billing/header.html'}
+
+    <table class="glm-admin-table">
+        <tr>
+            <td colspan="2" align="">
+            </td>
+        </tr>
+    </table>
+
+    <table class="glm-admin-table">
+        <tr><th>Number of Pending Invoices Listed: </th><td> replace me </td></tr>
+    </table>
+
+{include file='admin/footer.html'}