Working on the invoices.
creating some invoices and adding line items for each one.
still working out how need to create member account entry when none exists.
This could be done on the create invoice page so they pick a member name and
fill in the account data. I don't think I have a field yet for their account
number. may need that.Working on the account part of the add invoice page.
also trying to add due date to the form but it's not being saved.
--- /dev/null
+<?php
+/**
+ * GLM Member-DB WordPress Add-On Plugin
+ * Data Class Management
+ *
+ * PHP version 5.3
+ *
+ * @category Data
+ * @package GLM Member-DB
+ * @author Chuck Scott <cscott@gaslightmedia.com>
+ * @license http://www.gaslightmedia.com Gaslightmedia
+ * @release SVN: $Id: dataEvents.php,v 1.0 2011/01/25 19:31:47 cscott Exp $
+ */
+
+/**
+ * GlmDataBillingManagement class
+ *
+ * PHP version 5
+ *
+ * @category Data
+ * @package GLM Member DB
+ * @author Chuck Scott <cscott@gaslightmedia.com>
+ * @license http://www.gaslightmedia.com Gaslightmedia
+ * @release SVN: $Id: dataMembers.php,v 1.0 2011/01/25 19:31:47 cscott
+ * Exp $
+ */
+class GlmDataAccounts extends GlmDataAbstract
+{
+
+ /**
+ * WordPress Database Object
+ *
+ * @var $wpdb
+ * @access public
+ */
+ public $wpdb;
+ /**
+ * Plugin Configuration Data
+ *
+ * @var $config
+ * @access public
+ */
+ public $config;
+ /**
+ * Data Table Name
+ *
+ * @var $table
+ * @access public
+ */
+ public $table;
+ /**
+ * Field definitions
+ *
+ * 'type' is type of field as defined by the application
+ * text Regular text field
+ * pointer Pointer to an entry in another table
+ * 'filters' is the filter name for a particular filter ID in PHP filter
+ * functions
+ * See PHP filter_id()
+ *
+ * 'use' is when to use the field
+ * l = List
+ * g = Get
+ * n = New
+ * i = Insert
+ * e = Edit
+ * u = Update
+ * d = Delete
+ * a = All
+ *
+ * @var $ini
+ * @access public
+ */
+ public $fields = false;
+
+ /**
+ * Constructor
+ *
+ * @param object $d database connection
+ * @param array $config Configuration array
+ * @param bool $limitedEdit Flag to say indicate limited edit requested
+ *
+ * @return void
+ * @access public
+ */
+ public function __construct($wpdb, $config, $limitedEdit = false)
+ {
+
+ // If this class is not being extended along with existing $wpdb and $config
+ if (!$this->wpdb) {
+
+ // Save WordPress Database object
+ $this->wpdb = $wpdb;
+
+ // Save plugin configuration object
+ $this->config = $config;
+
+ }
+
+ /*
+ * Table Name
+ */
+ $this->table = GLM_MEMBERS_BILLING_PLUGIN_DB_PREFIX . 'accounts';
+
+ /*
+ * Table Data Fields
+ */
+
+ $this->fields = array (
+
+ 'id' => array (
+ 'field' => 'id',
+ 'type' => 'integer',
+ 'view_only' => true,
+ 'use' => 'a',
+ ),
+
+ // Account ref to accounts table
+ 'ref_dest' => array(
+ 'field' => 'ref_dest',
+ 'type' => 'pointer',
+ 'p_table' => GLM_MEMBERS_PLUGIN_DB_PREFIX . 'members',
+ 'p_field' => 'name',
+ 'p_orderby' => 'name',
+ 'p_blank' => true,
+ 'force_list' => true,
+ 'required' => false,
+ 'use' => 'a'
+ ),
+
+ // Name of red_dest
+ 'ref_name' => array(
+ 'field' => 'ref_name',
+ 'type' => 'text',
+ 'use' => 'a',
+ ),
+
+ // Anniversary Date
+ 'anniversary_date' => array(
+ 'field' => 'anniversary_date',
+ 'type' => 'date',
+ 'use' => 'a',
+ ),
+
+ // Payment Data
+ 'payment_data' => array(
+ 'field' => 'payment_data',
+ 'type' => 'text',
+ 'use' => 'a',
+ ),
+
+ // Email
+ 'email' => array(
+ 'field' => 'email',
+ 'type' => 'text',
+ 'use' => 'a',
+ ),
+
+ );
+
+
+ }
+
+ /*
+ * Entry Post Processing Call-Back Method
+ *
+ * Perform post-processing for all result entries.
+ *
+ * In this case we're using it to append an array of category
+ * data to each member result and also sort by member name.
+ *
+ * @param array $r Array of field result data for a single entry
+ * @param string $a Action being performed (l, i, g, ...)
+ *
+ * @return object Class object
+ *
+ */
+ public function entryPostProcessing($r, $a)
+ {
+ return $r;
+ }
+
+}
'use' => 'a'
),
- // Anniversary Date For ref_dest
+ // Amount Total
'amount_total' => array(
'field' => 'amount_total',
'type' => 'text',
'use' => 'a',
),
- // paid
+ // Paid
'paid' => array(
'field' => 'paid',
'type' => 'checkbox',
*/
public function entryPostProcessing($r, $a)
{
+ $sql = "
+ SELECT M.name
+ FROM " . GLM_MEMBERS_PLUGIN_DB_PREFIX . "members M,
+ " . GLM_MEMBERS_BILLING_PLUGIN_DB_PREFIX . "invoices I,
+ " . GLM_MEMBERS_BILLING_PLUGIN_DB_PREFIX . "accounts A
+ WHERE A.ref_dest = M.id
+ AND I.account = A.id";
+ $r['member_name'] = $this->wpdb->get_var( $sql );
return $r;
}
+ /**
+ * generateInvoiceTotal
+ *
+ * Grab all the line items and create the totals for invoice.
+ *
+ * @access public
+ * @return array
+ */
+ public function generateInvoiceTotal( $id )
+ {
+ $amount_total = $balance = 0.00;
+ $line_items = $this->wpdb->get_results(
+ $this->wpdb->prepare(
+ "SELECT *
+ FROM " . GLM_MEMBERS_BILLING_PLUGIN_DB_PREFIX . "line_items LI
+ WHERE LI.invoice = %d",
+ $id
+ )
+ , ARRAY_A
+ );
+ foreach( $line_items as $line_item ) {
+ $amount_total += $line_item['amount'];
+ }
+ $balance = $amount_total;
+ $this->wpdb->update(
+ GLM_MEMBERS_BILLING_PLUGIN_DB_PREFIX . 'invoices',
+ array(
+ 'amount_total' => $amount_total,
+ 'balance' => $balance,
+ ),
+ array( 'id' => $id ),
+ array( '%s', '%s' ),
+ array( '%d' )
+ );
+ return array(
+ 'amount_total' => $amount_total,
+ 'balance' => $balance,
+ );
+ }
+
+
}
#billing-invoice-form .glm-column {
padding: 0;
}
+#billing-invoice-form input[name^="line_item_qty"] {
+ width: 50px;
+}
// Load Contacts data class
require_once GLM_MEMBERS_BILLING_PLUGIN_CLASS_PATH.'/data/dataInvoices.php';
require_once GLM_MEMBERS_BILLING_PLUGIN_CLASS_PATH.'/data/dataInvoiceTypes.php';
+require_once GLM_MEMBERS_BILLING_PLUGIN_CLASS_PATH.'/data/dataAccounts.php';
class GlmMembersAdmin_billing_invoices extends GlmDataInvoices
{
/**
* Transactions ID
*
- * @var $transactionID
+ * @var $invoice_id
* @access public
*/
- public $transactionID = false;
+ public $invoice_id = false;
/**
* Constructor
{
$option = 'list';
- $this->transactionID = false;
+ $this->invoice_id = false;
$haveInvoices = false;
$invoiceUpdated = false;
$invoiceUpdateError = false;
$invTypes = array();
$invoiceTypes = false;
$invoiceTypeJSON = '';
+ $accounts = false;
// Get any provided option
if (isset($_REQUEST['option'])) {
$view = 'editInvoice';
$InvoiceTypesObj = new GlmDataInvoiceTypes( $this->wpdb, $this->config );
$invoiceTypes = $InvoiceTypesObj->getList();
+ // Sort the types by parent child
$invoiceTypes = $InvoiceTypesObj->sortParentChild($invoiceTypes);
- // echo '<pre>$invoiceTypes: ' . print_r( $invoiceTypes, true ) . '</pre>';
+ // Need to get the accounts
+ $Accounts = new GlmDataAccounts( $this->wpdb, $this->config );
+ $accounts = $Accounts->getList();
+ // echo '<pre>$accounts: ' . print_r( $accounts, true ) . '</pre>';
if ( isset( $invoiceTypes ) ) {
foreach ( $invoiceTypes as $invoiceType ) {
$invTypes[$invoiceType['id']] = array(
'amount' => $invoiceType['amount'],
);
}
- $invoiceTypeJSON = json_encode( $invTypes, true );
+ $invoiceTypeJSON = json_encode( $invTypes, JSON_NUMERIC_CHECK );
}
break;
// Set transaction_time to current time.
$_REQUEST['transaction_time'] = date('Y-m-d H:i:s');
echo '<pre>' . print_r( $_REQUEST, true ) . '</pre>';
+ $_REQUEST['due_date'] = date('Y-m-d', strtotime($_REQUEST['due_date']));
$invoices = $this->insertEntry();
- $this->transactionID = $invoices['fieldData']['id'];
+ $this->invoice_id = $invoices['fieldData']['id'];
+ // After the Invoice is created need to add each line item
+ if ( isset( $_REQUEST['line_items'] ) ) {
+ $line_items = $_REQUEST['line_items'];
+ if ( is_array( $line_items ) && !empty( $line_items ) ) {
+ foreach ( $line_items as $key => $line_item ) {
+ // Add individual line item record
+ $this->wpdb->insert(
+ GLM_MEMBERS_BILLING_PLUGIN_DB_PREFIX . 'line_items',
+ array(
+ 'invoice' => $this->invoice_id,
+ 'line_item_type' => $line_item,
+ 'name' => $_REQUEST['line_item_name'][$line_item],
+ 'amount' => $_REQUEST['line_item_amount'][$line_item],
+ 'quantity' => $_REQUEST['line_item_qty'][$line_item],
+ ),
+ array(
+ '%d',
+ '%d',
+ '%s',
+ '%s',
+ '%d',
+ )
+ );
+ }
+ }
+ }
+ $this->generateInvoiceTotal( $this->invoice_id );
$view = 'editInvoice';
+ $InvoiceTypesObj = new GlmDataInvoiceTypes( $this->wpdb, $this->config );
+ $invoiceTypes = $InvoiceTypesObj->getList();
+ $invoiceTypes = $InvoiceTypesObj->sortParentChild($invoiceTypes);
+ if ( isset( $invoiceTypes ) ) {
+ foreach ( $invoiceTypes as $invoiceType ) {
+ $invTypes[$invoiceType['id']] = array(
+ 'id' => $invoiceType['id'],
+ 'name' => $invoiceType['name'],
+ 'amount' => $invoiceType['amount'],
+ );
+ }
+ $invoiceTypeJSON = json_encode( $invTypes, true );
+ }
break;
case 'edit':
- $invoices = $this->editEntry($this->transactionID);
+ $invoices = $this->editEntry($this->invoice_id);
// If we have a good invoices
if ($invoices['status']) {
case 'update':
// Try to update this invoices
- $invoices = $this->updateEntry($this->transactionID);
+ $invoices = $this->updateEntry($this->invoice_id);
// Check if that was successful
if ($invoices['status']) {
$invoiceUpdated = true;
- $invoices = $this->editEntry($this->transactionID);
+ $invoices = $this->editEntry($this->invoice_id);
} else {
$invoiceUpdateError = true;
}
break;
case 'delete':
-
- $invoices = $this->deleteTransactions($this->transactionID);
+ // Need to remove any line items for the invoice alse
+ // $invoices = $this->deleteTransactions($this->invoice_id);
if ($invoices) {
$invoiceDeleted = true;
}
unset($invoicesResult);
+ // echo '<pre>$invoices: ' . print_r( $invoices, true ) . '</pre>';
+
+ foreach ( $invoices as $invoice ) {
+ // $this->generateInvoiceTotal( $invoice['id'] );
+ }
+
break;
}
+
$templateData = array(
'option' => $option,
'invoices' => $invoices,
'limit' => $limit,
'invoiceTypeJSON' => $invoiceTypeJSON,
'invoiceTypes' => $invoiceTypes,
+ 'accounts' => $accounts,
);
// Return status, any suggested view, and any data to controller
{/if}
<div class="glm-row">
<div class="glm-columns glm-small-12 glm-large-8">
+
<div class="glm-row">
- <div class="glm-columns glm-small-12 glm-large-3">
+ <div class="glm-columns glm-small-12 glm-large-3 glm-required">
Member Account
</div>
<div class="glm-columns glm-small-12 glm-large-9">
<select name="account" required>
<option value="">Select an Account</option>
- <option value="3204">A Test Member</option>
+ {foreach $accounts as $account}
+ <option value="{$account.id}">{$account.ref_name}</option>
+ {/foreach}
</select>
</div>
</div>
+ <div class="glm-row">
+ <div class="glm-columns glm-small-12 glm-large-3 glm-required">
+ Due Date
+ </div>
+ <div class="glm-columns glm-small-12 glm-large-9">
+ <input type="text" name="due_date" required>
+ </div>
+ </div>
+
</div>
</div>
<div class="glm-row">
</div>
<div class="glm-columns glm-small-12 glm-large-10">
<div class="glm-row">
- <div class="glm-columns glm-small-8"> Total Amount: </div>
+ <div class="glm-columns glm-small-8" style="text-align: right;"> Total Amount: </div>
<div class="glm-columns glm-small-4" id="invoice-total"> $0.00 </div>
</div>
</div>
<script>
jQuery(document).ready(function($){
+ // Initialize variables for this page.
var invoiceTypeJSON = $.parseJSON( '{$invoiceTypeJSON}' );
var dialog, form,
line_item_type = $( 'select[name="line_item_type"]' ),
line_items = [],
allFields = $( [] ).add( line_item_type );
+ /**
+ * totalInvoice
+ *
+ * Totals up all amounts that are in the line_items array.
+ *
+ * @access public
+ * @return void
+ */
function totalInvoice() {
var totalAmount = 0.00;
for ( var i = 0; i < line_items.length; ++i ) {
- totalAmount += parseFloat( line_items[i].amount );
+ totalAmount += parseFloat( line_items[i].amount ) * line_items[i].qty;
}
$('#invoice-total').html('$' + totalAmount.toFixed( 2 ) );
}
+ /**
+ * isLineItem
+ *
+ * Checks to see if this item is a line item already.
+ *
+ * @param item $item JSON item to check in line_items array.
+ *
+ * @access public
+ * @return void
+ */
function isLineItem( item ) {
for ( var i = 0; i < line_items.length; ++i ) {
if ( item.id === line_items[i].id ) {
return false;
}
+ /**
+ * addLineItem
+ *
+ * Callback function for the jqueryui modal form for adding a line item.
+ * Creates the line item and the input fields needed for the invoice form.
+ *
+ * @access public
+ * @return void
+ */
function addLineItem() {
var valid = true;
allFields.removeClass( 'ui-state-error' );
var selectedLineItem = invoiceTypeJSON[line_item_type.val()];
// Check first to see if this line_item_type is already in line_items.
if ( !isLineItem( selectedLineItem ) ) {
+ selectedLineItem.qty = parseInt(1);
line_items.push( selectedLineItem );
- console.log( line_items );
$( '#invoice-line-items' ). append( '<div class="glm-row" id="line-item-type-' + selectedLineItem.id + '">' +
'<div class="glm-columns glm-small-7">' + selectedLineItem.name + '</div>' +
- '<div class="glm-columns glm-small-1">1</div>' +
- '<div class="glm-columns glm-small-4">$' + selectedLineItem.amount + '</div>' +
+ '<div class="glm-columns glm-small-1">' +
+ '<input type="number" min="0" data-id="' + selectedLineItem.id + '" name="line_item_qty[' + selectedLineItem.id + ']" value="1">' +
+ '</div><div class="glm-columns glm-small-4">' +
+ '<input type="hidden" name="line_items[]" value="' + selectedLineItem.id + '">' +
+ '<input type="hidden" name="line_item_amount[' + selectedLineItem.id + ']" value="' + selectedLineItem.amount + '">' +
+ '<input type="hidden" name="line_item_name[' + selectedLineItem.id + ']" value="' + selectedLineItem.name + '">' +
+ '$' + selectedLineItem.amount + '</div>' +
'</div>');
} else {
// Code here to add to quantity.
+ selectedLineItem.qty++;
+ $('input[name="line_item_qty\\[' + selectedLineItem.id + '\\]').val(selectedLineItem.qty);
}
dialog.dialog( 'close' );
}
return valid;
}
+ /**
+ * checkRequired
+ *
+ * Checks that the field has a value.
+ *
+ * @param fieldName $fieldName
+ * @access public
+ * @return void
+ */
function checkRequired( fieldName ) {
if ( fieldName.val() ) {
return true;
}
}
+ /**
+ * dialog
+ *
+ * jqueryui dialog box for the add line item form.
+ */
dialog = $('#newLineItemDialog').dialog({
autoOpen: false,
minWidth: 400,
},
});
+ /**
+ * form
+ *
+ * form with id of #addLineItemForm
+ */
form = dialog.find( '#addLineItemForm' ).on( 'submit', function(){
event.preventDefault();
addLineItem();
});
+ /**
+ * Click event for the id of #newLineItemButton.
+ *
+ * Activates the dialog for adding line items.
+ */
$('#newLineItemButton').click( function() {
$("#newLineItemDialog").dialog("open");
+ return false;
});
- $('.glm-billing-add-line-item').on( 'click', function(){
- return false;
+ /**
+ * Onchange event for the qty fields.
+ * So the line_items array gets updated with the qty number.
+ */
+ $('#invoice-line-items').on('change', 'input[name^="line_item_qty"]', function(){
+ var itemId = $(this).data('id');
+ // Update the qty for this line item in the json object
+ for ( i = 0; i < line_items.length; i++ ) {
+ if ( line_items[i].id == itemId ) {
+ line_items[i].qty = parseInt( $(this).val() );
+ }
+ }
+ totalInvoice();
});
+ $('input[name="due_date"]').datepicker();
+
// Flash certain elements for a short time after display
$(".glm-flash-updated").fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500);
<thead>
<tr>
<th>ID</th>
- <th>InvoiceType</th>
- <th>Amount</th>
- <th>Recurring</th>
- <th>Recurrence</th>
- <th> </th>
+ <th>Member Name</th>
+ <th>Time</th>
+ <th>Due Date</th>
+ <th>Balance</th>
</tr>
</thead>
<tbody>
{if $haveInvoices}
{assign var="i" value="0"}
- {foreach $invoiceTypes as $t}
+ {foreach $invoices as $t}
{if $i++ is odd by 1}
<tr>
{else}
<tr class="alternate">
{/if}
<td>{$t.id}</td>
- <td>
- <div{if $t.parent.value} class="glm-indent"{/if}>
- <a class="editInvoiceType"
- data-invoice-id="{$t.id}"
- >{$t.name}</a>
- </div>
- </td>
- <td>{$t.amount}</td>
- <td>{if $t.recurring.value}Yes{else}No{/if}</td>
- <td>{if $t.recurrence}{$recurrenceTypes[$t.recurrence]}{/if}</td>
- <td>
- <div class="deleteInvoiceTypeButton button button-secondary glm-button-small glm-right"
- data-invoiceTypeID="{$t.id}">Delete</div>
- </td>
+ <td> {$t.member_name} </td>
+ <td> {$t.transaction_time.datetime} </td>
+ <td> {$t.due_date} </td>
+ <td> {$t.balance} </td>
</tr>
{/foreach}
{else}