Merge branch 'develop' of https://github.com/CORE-POS/IS4C into devel
New config:  houseCoupon UPC prefix is configurable via the Scanning page in /install
SCALE command pulls current weight into input box
Report with a chart!
Another library on top of d3.js might be nice. It's powerful
but complex.
Reports refactored for classes / consistency:
* Hourly Transactions
* Movement w/ margin
* Movement by Price
* New Items
* Open Rings
* Patronage Rebate
* Product Recall
I also update Hourly Sales so that it automatically links
to Hourly Transactions for the same dates & departments
(and vice versa). I updated the default menus to use the
newer hourly reports.
BUGFIX: Insert query column misaligned when creating shelf tags
by department or manufacturer
Class-based Report Refactors:
* RecentSales
* SalePerformance
* StockSummary
* SuspensionHistory
* TenderInOut
* Trends

I extended the ProductMovement report to search non-numeric
UPCs differently. I use this for tracking POS logging records.

SQLManager has a new week() method for getting the week #.

SalesToday is NOT an instance of FannieReportPage although it is
class based. There's not that much data and it's only live so
export makes no sense. I added a line graph using d3.js.
BUGFIX: query response variable was incorrect
Single line graph separated out as standalone js/css. Hourly sales
and transactions use the same charting. FannieReportPage tags columns
with a class attribute to make them JS-accessible.
BasicModel::load() and BasicModel::save() cope with missing columns
BasicModel::find() also needs to avoid missing columns
Hook function for Model classes to register a callback that is executed
after a column is successfully added
New BasicModel functionality to normalize lane tables in conjunection
with server tables.
Safely Renaming a Column in custdata, pt 1

======================================
STEP ONE: Define a New Column
======================================
Edit CustdataModel.php and define a ChargeLimit column.
Re-run BasicModel on it to update accessors.

php BasicModel.php CustdataModel.php

Add a hook function Custdata::hookAddColumnChargeLimit
to copy the current values in custdata.MemDiscountLimit
to the new column. The view memChargeBalance also
needs to be rebuilt using the new column.

Edit install/sql/op/custdata.php so new installs will
have the column without needing an update. Ditto
for install/sql/trans/memChargeBalance.php.

Since the lane table needs to match, set
$normalize_lanes to true for CustdataModel. The hook
function needs a different definition for the lane-side
memchargebalance view. The install scripts should
also be updated on the lane side.

Now it's time to run the update. Manually creating a
backup of custdata would not be a bad idea.

php BasicModel.php --update <database name> CustdataModel.php

======================================
STEP TWO: Code Revisions
======================================
First pass goal is to use both columns. Any place
that updates custdata.MemDiscountLimit should
also update custdata.ChargeLimit. Places that
use the value of custdata.MemDiscountLimit should
use custdata.ChargeLimit instead.

None of this code should break if the new column
is not yet present. Models simplify some of that but
there are still some sections of defensive coding.
Case sensitivity: MemDiscountLimit should have capital M
BUGFIX: syntax error on batch cut/paste queries
Safely Renaming a Column in custdata, pt 2
======================================
Fannie Cleanup
======================================
Remove unnecessary references to MemDiscountLimit.
Omitting it from INSERTs is safe because it has
a default value. Letting a model class handle
INSERTs is better because only the model will
need revisions if MemDiscountLimit is removed
entirely.

Also legacy and store-specific revisions. Code
here just assumed custdata.ChargeLimit exists.
Unnecessary references to MemDiscountLimit are
again removed so the column itself can be
eliminated in the future.
Safely Renaming a Column in custdata, pt 3
======================================
Lane Code Cleanup
======================================
Easy. The lane only access the limit value
via the memchargebalance view which has
already been updated. So this just removes
stale references.

PrehLib and the gui-modules all issue the same
query to get a record from custdata. The query
requests the MemDiscountLimit column but never
does anything with it. No reason to have the
column name there.

CoreState looks up the limit value in its
crash recovery function but does not do anything
useful with it. Again no reason to have the column
name there.
Override default styles so text prints black reliably.
Graph on single item movement. Support for Date values in singleline chart.