Updates to grocery price application

I recently posted about a grocery tracking database/application I had built using Xataface.  Today I circled back to it for a bit and made a couple of updates to provide some additional functionality and to fix a couple of behaviors I found marginally annoying.

I started out with some reading about delegate classes and how to create them, which was instrumental in creating the changes described below.  Essentially in my case, the initial creation of the delegate class was fairly simple.  I created a new file owned by the HTTP server user at grocery/tables/entry/entry.php.  Initially, the contents of this file were pretty basic:

<? 
class tables_entry { 

}
?>

One of my goals was to improve the speed of entry from my receipts, and I saw a couple of potential methods for this.  I ran across an article about adding a CSV import and added that code into my delegate class (inside the {}’s for the class) and thought it might simplify additions with a lot of common fields – such as the date, store, and location for a particular receipt.  Please note that I have not given any thought to the security or sanity checks on this code, and it may be unsafe against injection attacks.


function __import__csv(&$data, $defaultValues=array()){
    // build an array of Dataface_Record objects that are to be inserted based
    // on the CSV file data.
    $records = array();

    // first split the CSV file into an array of rows.
    $rows = explode("\n", $data);
    foreach ( $rows as $row ){
        // We iterate through the rows and parse the name, phone number, and email
        // addresses to that they can be stored in a Dataface_Record object.
        list($brand, $type, $subtype, $description, $count, $size, $unit, $price, $priceisperitem, $regularprice, $store, $rcptdesc, $sku, $pricedate, $location, $note) = explode(',', $row);
        $record = new Dataface_Record('entry', array());

        // We insert the default values for the record.
        $record->setValues($defaultValues);

        // Now we add the values from the CSV file.
        $record->setValues(
            array(
                'Brand'=>$brand,
                'Type'=>$type,
                'Subtype'=>$subtype,
                'Description'=>$description,
                'Count'=>$count,
                'Size'=>$size,
                'Unit'=>$unit,
                'Price'=>$price,
                'Priceisperitem'=>$priceisperitem,
                'Regularprice'=>$regularprice,
                'Store'=>$store,
                'Rcptdesc'=>$rcptdesc,
                'Sku'=>$sku,
                'Pricedate'=>$pricedate,
                'Location'=>$location,
                'Note'=>$note
                 )
            );

        // Now add the record to the output array.
        $records[] = $record;
    }

    // Now we return the array of records to be imported.
    return $records;
}

My thought was that I could pre-fill common fields for a particular shopping trip and save some time.  Unfortunately, after trying it I was somewhat disappointed at the amount of time it took me to enter things as comma separated lines, and the code isn’t working quite right as the pre-filled values are the only things that come through.  So instead I turned my focus towards improving the process I already use.

Like most people, we make quite a few repeat purchases and generally shop the same few stores.  As such, I already have many items in the database and only need to search, copy, and change a field or two (pricedate, perhaps the price or a note) for the new record.  This works pretty well, but the field modification when copying a record from a search with multiple items returned bugs me just a little bit – the pre-fill in the field modifications might not match the data from the record you copied, but from another record in the search instead.  This doesn’t happen when only one record is returned.  So, I added another function to my delegate class to allow me to focus on just one row of a search.  Now I just have to click a “Go To” link, and I have a single record that I can copy and know my pre-fill boxes will be right if I accidentally hit a field I don’t need to modify!  Here’s the code (this also goes inside the {}’s for the class, but NOT inside the ones for the function I previously defined).

function entryID__renderCell ( &$record ) {
        //LV 2013-02-23
        //Wrote based on variable info at http://xataface.com/wiki/Creating_a_Dashboard
        //and renderCell info at http://xataface.com/documentation/how-to/list_tab
        return $record->strval('entryID').'<br>(<a href="'.$ENV.DATAFACE_SITE_HREF.'?-action=list&-table=entry&entryID='.$record->strval('entryID').'">Go To</a>)';
        }

This worked slick, and with an initial foray into renderCell under my belt, I was comfortable tackling another one to allow me to quickly display all the records of a particular brand – which I may later extend to a couple of other fields as well.  That code is as follows, with the same stipulations on placement as noted above.

function brand__renderCell ( &$record ) {
        //LV 2013-02-23
        //Wrote based on variable info at http://xataface.com/wiki/Creating_a_Dashboard
        //and renderCell info at http://xataface.com/documentation/how-to/list_tab
        return $record->strval('brand').'<br>(<a href="'.$ENV.DATAFACE_SITE_HREF.'?-action=list&-table=entry&brand='.$record->strval('brand').'">View&nbsp;All</a>)';
        }

I also fixed a couple of fields that were not hidden in my list view previously based upon the information here.  In my fields.ini file, I changed “widget:type” to “visibility:list”, and the unnecessary fields disappeared from view, just as I had desired.

Now I just need to find a decent code-formatting/including plugin for WordPress, as the “code” syntax leaves a little to be desired and it would be fantastic if it displayed with the same syntax highlighting I get in Vi 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *