Merge pull request #1784 from garyhgohoos/23593-2
authorSteve Hackbarth <stephenhackbarth@gmail.com>
Wed, 17 Sep 2014 14:43:08 +0000 (10:43 -0400)
committerSteve Hackbarth <stephenhackbarth@gmail.com>
Wed, 17 Sep 2014 14:43:08 +0000 (10:43 -0400)
Issue #23593:correctly handle nulls in address

112 files changed:
.gitignore
.travis.yml
README.md
RELEASE.md [deleted file]
enyo-client/application/source/models/address.js
enyo-client/application/source/models/site.js
enyo-client/application/source/views/list.js
enyo-client/application/source/views/module_container.js
enyo-client/application/source/views/workspace.js
enyo-client/database/orm/models/customer.json
enyo-client/database/orm/models/employee.json
enyo-client/database/orm/models/site.json
enyo-client/database/source/xt/functions/cust_outstanding_credit.sql
enyo-client/database/source/xt/views/itemsiteinfo.sql
enyo-client/extensions/source/billing/client/core.js
enyo-client/extensions/source/billing/database/source/xt/tables/rptdef.sql
enyo-client/extensions/source/crm/client/core.js
enyo-client/extensions/source/oauth2/client/core.js
enyo-client/extensions/source/oauth2/client/en/strings.js
enyo-client/extensions/source/project/client/core.js
enyo-client/extensions/source/purchasing/client/core.js
enyo-client/extensions/source/sales/client/core.js
foundation-database/manifest.js
foundation-database/postbooks_demo_data.sql
foundation-database/public/functions/assessfinancecharge.sql
foundation-database/public/functions/avgcost.sql
foundation-database/public/functions/balanceitemsite.sql
foundation-database/public/functions/convertquote.sql
foundation-database/public/functions/convertquotetoinvoice.sql
foundation-database/public/functions/copyitemsite.sql
foundation-database/public/functions/deleteitemsite.sql
foundation-database/public/functions/detailednnqoh.sql
foundation-database/public/functions/detailedqoh.sql
foundation-database/public/functions/distributeitemlocseries.sql
foundation-database/public/functions/distributetolocations.sql
foundation-database/public/functions/getsoitemstatus.sql
foundation-database/public/functions/importbankreccleared.sql [new file with mode: 0644]
foundation-database/public/functions/indentedwo.sql
foundation-database/public/functions/indentedwomatl.sql
foundation-database/public/functions/initialdistribution.sql
foundation-database/public/functions/iteminventoryuominuse.sql
foundation-database/public/functions/postcounttag.sql
foundation-database/public/functions/postcounttaglocation.sql
foundation-database/public/functions/postinvtrans.sql
foundation-database/public/functions/qtyatlocation.sql [new file with mode: 0644]
foundation-database/public/functions/qtyavailable.sql
foundation-database/public/functions/qtynetable.sql [new file with mode: 0644]
foundation-database/public/functions/relocateinventory.sql
foundation-database/public/functions/sufficientinventorytoshipitem.sql
foundation-database/public/functions/thawitemsite.sql
foundation-database/public/functions/updatestdcost.sql
foundation-database/public/functions/woinvavail.sql
foundation-database/public/functions/woinvavailmatl.sql
foundation-database/public/tables/bankrecimport.sql [new file with mode: 0644]
foundation-database/public/tables/bankrecimport.xml [new file with mode: 0644]
foundation-database/public/tables/itemsite.sql [new file with mode: 0644]
foundation-database/public/tables/location.sql
foundation-database/public/tables/metasql/apOpenItems-selectedpayments.mql
foundation-database/public/tables/metasql/apOpenItems-selectpayments.mql
foundation-database/public/tables/metasql/bookings-detail.mql
foundation-database/public/tables/metasql/countTag-detail.mql
foundation-database/public/tables/metasql/distributeInventory-locations.mql
foundation-database/public/tables/metasql/inventoryAvailability-byCustOrSO.mql
foundation-database/public/tables/metasql/inventoryAvailability-general.mql
foundation-database/public/tables/metasql/inventoryLocator-detail.mql
foundation-database/public/tables/metasql/mrpDetail-detail.mql
foundation-database/public/tables/metasql/pendingAvailability-detail.mql
foundation-database/public/tables/metasql/purchase-purchaserequests.mql
foundation-database/public/tables/metasql/qoh-detail.mql
foundation-database/public/tables/metasql/reorderExceptionsByPlannerCode-detail.mql
foundation-database/public/tables/metasql/runningAvailability-detail.mql
foundation-database/public/tables/metasql/salesOrderItems-list.mql
foundation-database/public/tables/metasql/substituteAvailability-detail.mql
foundation-database/public/tables/metasql/unbalancedQOHByClassCode-detail.mql
foundation-database/public/tables/metric.sql
foundation-database/public/tables/report/InventoryAvailability.xml
foundation-database/public/tables/report/InventoryAvailabilityByCustomerType.xml
foundation-database/public/tables/report/InventoryAvailabilityBySalesOrder.xml
foundation-database/public/tables/report/InventoryAvailabilityBySourceVendor.xml
foundation-database/public/tables/report/PackingList-Shipment.xml
foundation-database/public/tables/report/ReorderExceptionsByPlannerCode.xml
foundation-database/public/tables/report/RunningAvailability.xml
foundation-database/public/tables/report/SubstituteAvailabilityByRootItem.xml
foundation-database/public/tables/setVersion.sql [new file with mode: 0644]
foundation-database/public/trigger_functions/itemsite.sql
foundation-database/public/trigger_functions/location.sql
lib/enyo-x/source/less/screen.less
lib/enyo-x/source/stylesheets/screen.css
lib/enyo-x/source/views/module_container.js
lib/orm/source/xt/functions/add_comment_type.sql [new file with mode: 0644]
node-datasource/main.js
node-datasource/routes/generate_oauth_key.js
node-datasource/views/login.ejs
node-datasource/views/login/stylesheets/screen.css
node-datasource/xt/xt.js
npm-shrinkwrap.json
package.json
scripts/install_xtuple.sh
scripts/lib/build_all.js
scripts/lib/build_dictionary.js
scripts/lib/util/init_database.js
test/extensions/all/configure.js
test/extensions/all/workspace.js
test/extensions/crm/characteristics.js
test/extensions/sales/sales_order_workspace.js
test/lib/crud.js
test/lib/runner_engine.js
test/lib/smoke.js
test/lib/zombie_auth.js
test/specs/country.js
test/specs/invoice.js
test/specs/site.js

index 1892508..76887af 100644 (file)
@@ -1,3 +1,4 @@
+*.log
 *.DS_Store
 *.sw*
 *~
index 7d0d3a4..10dcc2b 100644 (file)
@@ -1,6 +1,6 @@
 language: node_js
 node_js:
-  - "0.8"
+  - "0.10"
 
 install:
   - "bash scripts/install_xtuple.sh -ipn"
index cce4569..ed58ba9 100644 (file)
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ Fork us, take a test drive with our [free trial](http://www.xtuple.com/free-tria
 file a github issue. 
 If you want to be a contributor and are looking for a place to
 make your mark, we're keeping a list of issues that are 
-[fair game](https://github.com/xtuple/xtuple/issues?labels=fair+game) 
+[fair game](https://github.com/xtuple/xtuple/labels/fair%20game)
 to pick off and provide
 a convenient, well-documented starting point into our project.
 
@@ -61,7 +61,8 @@ The best way to start coding on our stack is to use our
 
 ### Release Notes
 
-View the [Release Notes](RELEASE.md) to see a change log.
+View the [Release Notes](https://github.com/xtuple/xtuple-documentation/tree/master/release-notes) 
+to see a change log.
 
 ### Additional Resources
   * [Building an Extension Tutorial](https://github.com/xtuple/xtuple-extensions/blob/master/docs/TUTORIAL.md)
diff --git a/RELEASE.md b/RELEASE.md
deleted file mode 100644 (file)
index e7039d6..0000000
+++ /dev/null
@@ -1,2102 +0,0 @@
-4.6.0-beta (2014/07/21)
-=======================
-
-Features and bugfixes
----------------------
-
-- Fixed
-  issue #[18401](http://www.xtuple.org/xtincident/view/bugs/18401)
-  _Relation autocompleter menu gets in the way_
-- Fixed
-  issue #[18409](http://www.xtuple.org/xtincident/view/bugs/18409)
-  _blank screen after login, selecting DB_
-- Fixed
-  issue #[18505](http://www.xtuple.org/xtincident/view/bugs/18505)
-  _Advanced search panel is blank on iPad_
-- Fixed
-  issue #[18521](http://www.xtuple.org/xtincident/view/bugs/18521)
-  _Automatically-added comments have "admin" as the name_
-- Fixed
-  issue #[18635](http://www.xtuple.org/xtincident/view/bugs/18635)
-  _Creating a user account in the mobile client does not create a CRM Account_
-- Implemented
-  issue #[18637](http://www.xtuple.org/xtincident/view/bugs/18637)
-  _Extend "Personal" privilege methodology to any property that can be tied back to a UserAccount ID_
-- Fixed
-  issue #[18640](http://www.xtuple.org/xtincident/view/bugs/18640)
-  _error in CRM Acct Merge_
-- Fixed
-  issue #[18692](http://www.xtuple.org/xtincident/view/bugs/18692)
-  _List Relation Box should be disabled for new records_
-- Fixed
-  issue #[18695](http://www.xtuple.org/xtincident/view/bugs/18695)
-  _Comments don't work on iPad_
-- Fixed
-  issue #[18698](http://www.xtuple.org/xtincident/view/bugs/18698)
-  _iPad sorts strings as numbers_
-- Fixed
-  issue #[18699](http://www.xtuple.org/xtincident/view/bugs/18699)
-  _iPad does not scroll smoothly_
-- Fixed
-  issue #[18707](http://www.xtuple.org/xtincident/view/bugs/18707)
-  _Can't switch databases on iPad_
-- Fixed
-  issue #[18730](http://www.xtuple.org/xtincident/view/bugs/18730)
-  _Task number read only status is erratic_
-- Fixed
-  issue #[18731](http://www.xtuple.org/xtincident/view/bugs/18731)
-  _Address placeholders are not translated_
-- Fixed
-  issue #[18732](http://www.xtuple.org/xtincident/view/bugs/18732)
-  _All postgres users are showing up in user list_
-- Fixed
-  issue #[18769](http://www.xtuple.org/xtincident/view/bugs/18769)
-  _Cookies are not being deleted in any test-cases_
-- Completed
-  issue #[18770](http://www.xtuple.org/xtincident/view/bugs/18770)
-  _Integrate node-router into node-datasource_
-- Fixed
-  issue #[19199](http://www.xtuple.org/xtincident/view/bugs/19199)
-  _Security on reset password._
-- Implemented
-  issue #[20689](http://www.xtuple.org/xtincident/view/bugs/20689)
-  _Support for Barcode_
-- Implemented
-  issue #[20962](http://www.xtuple.org/xtincident/view/bugs/20962)
-  _Add support to enter Receipt transactions_
-- Implemented
-  issue #[21038](http://www.xtuple.org/xtincident/view/bugs/21038)
-  _Complete Issue to Shipping_
-- Fixed
-  issue #[21476](http://www.xtuple.org/xtincident/view/bugs/21476)
-  _*Unable to select back 'External' option as the Gateway for Credit cards in System Configuration screen_
-- Implemented
-  issue #[21584](http://www.xtuple.org/xtincident/view/bugs/21584)
-  _Organize pentaho properties in config.js_
-- Fixed
-  issue #[21686](http://www.xtuple.org/xtincident/view/bugs/21686)
-  _*Toolbar overlaps the Export icon making it unable to select in mobile devices_
-- Fixed
-  issue #[21889](http://www.xtuple.org/xtincident/view/bugs/21889)
-  _Mobile Web Client List View Items Overlap_
-- Fixed
-  issue #[21909](http://www.xtuple.org/xtincident/view/bugs/21909)
-  _ErpBI configuration not production ready_
-- Fixed
-  issue #[21978](http://www.xtuple.org/xtincident/view/bugs/21978)
-  _Item auto-populates on Sales Order when it should not_
-- Implemented
-  issue #[22067](http://www.xtuple.org/xtincident/view/bugs/22067)
-  _Implement returns(credit memo)_
-- Implemented
-  issue #[22072](http://www.xtuple.org/xtincident/view/bugs/22072)
-  _Add support for Transfer Order_
-- Implemented
-  issue #[22129](http://www.xtuple.org/xtincident/view/bugs/22129)
-  _Support system printers for reports_
-- Fixed
-  issue #[22151](http://www.xtuple.org/xtincident/view/bugs/22151)
-  _Selecting ITEM-GROUP produces internal server error_
-- Fixed
-  issue #[22152](http://www.xtuple.org/xtincident/view/bugs/22152)
-  _Site is required in PostBooks_
-- Fixed
-  issue #[22172](http://www.xtuple.org/xtincident/view/bugs/22172)
-  _Item Group does not appear in Postbooks_
-- Implemented
-  issue #[22175](http://www.xtuple.org/xtincident/view/bugs/22175)
-  _Add the ability to issue to shipping and ship from Sales Order_
-- Fixed
-  issue #[22214](http://www.xtuple.org/xtincident/view/bugs/22214)
-  _Inventory gear options not showing on small devices_
-- Fixed
-  issue #[22224](http://www.xtuple.org/xtincident/view/bugs/22224)
-  _*Selecting 'Issue to Shipping' displays a JS console error and does not displays any response_
-- No Change Required
-  issue #[22227](http://www.xtuple.org/xtincident/view/bugs/22227)
-  _*Selecting to open an existing shipment hangs the application_
-- Fixed
-  issue #[22298](http://www.xtuple.org/xtincident/view/bugs/22298)
-  _*Selecting to add an address to a record displays an irrelevant dialog_
-- Fixed
-  issue #[22355](http://www.xtuple.org/xtincident/view/bugs/22355)
-  _Toolbar height changed_
-- Fixed
-  issue #[22368](http://www.xtuple.org/xtincident/view/bugs/22368)
-  _*Date format is displayed incorrectly in Transfer order list and Issue to shipping screens_
-- Fixed
-  issue #[22407](http://www.xtuple.org/xtincident/view/bugs/22407)
-  _*Selecting 'Issue to Shipping' without saving the Sales order and then selecting 'Save', doesn't populate the Sales order number_
-- Fixed
-  issue #[22408](http://www.xtuple.org/xtincident/view/bugs/22408)
-  _*Selecting Express Checkout without saving the Sales order and then selecting 'No' in the confirmation dialog displays a console_
-
-
-
-4.5.2 (2014/07/15)
-==================
-
-Features and bugfixes
----------------------
-- Fixed
-  issue #[23636](http://www.xtuple.org/xtincident/view/bugs/23636) 
-  _Error when running Inventory Availability_ 
-- Fixed 
-  issue #[23714](http://www.xtuple.org/xtincident/view/bugs/23714) 
-  _*Quantity 'At Shipping' gets doubled on selecting 'Issue All' or 'Issue Line' multiple times_ 
-- Fixed 
-  issue #[23979](http://www.xtuple.org/xtincident/view/bugs/23979) 
-  _*Unable to build Mobile Web client on empty databases_ 
-- Fixed 
-  issue #[24098](http://www.xtuple.org/xtincident/view/bugs/24098) 
-  _Icons only displaying when debugging = true_ 
-
-
-4.5.1 (2014/06/25)
-==================
-
-Features and bugfixes
----------------------
-- Fixed 
-  issue #[21772](http://www.xtuple.org/xtincident/view/bugs/21772) 
-  _*Error message is displayed in JS console on selecting to open a configure screen_ 
-- Implemented 
-  issue #[22128](http://www.xtuple.org/xtincident/view/bugs/22128) 
-  _Support filters for dashboards._ 
-- Fixed 
-  issue #[22218](http://www.xtuple.org/xtincident/view/bugs/22218) 
-  _Add support to print and email Sales Order acknowledgements_ 
-- Fixed 
-  issue #[22926](http://www.xtuple.org/xtincident/view/bugs/22926) 
-  _*'Backflush' option is available in the Post production screen for work orders with materials issued_ 
-- Implemented 
-  issue #[22996](http://www.xtuple.org/xtincident/view/bugs/22996) 
-  _signature capture_ 
-- Fixed 
-  issue #[23288](http://www.xtuple.org/xtincident/view/bugs/23288) 
-  _Can not open item work bench from Sales Order_ 
-- Implemented 
-  issue #[23796](http://www.xtuple.org/xtincident/view/bugs/23796) 
-  _Export grid list to csv_ 
-- Implemented 
-  issue #[23852](http://www.xtuple.org/xtincident/view/bugs/23852) 
-  _inventory component of invoice_ 
-- Implemented 
-  issue #[23853](http://www.xtuple.org/xtincident/view/bugs/23853) 
-  _refactor xv.input and xv.inputwidget_ 
-- Fixed 
-  issue #[23860](http://www.xtuple.org/xtincident/view/bugs/23860) 
-  _Handle "no data" case from dashboard filter_ 
-- Fixed 
-  issue #[23867](http://www.xtuple.org/xtincident/view/bugs/23867) 
-  _Add support to XT.Data for x.y.naturalKeyOfY queries_ 
-- Fixed 
-  issue #[23868](http://www.xtuple.org/xtincident/view/bugs/23868) 
-  _*Unable to edit sale order line item after opening item site from line item screen_ 
-- Fixed 
-  issue #[23876](http://www.xtuple.org/xtincident/view/bugs/23876) 
-  _update xwd and xtmfg pkghead_ 
-- Implemented 
-  issue #[23894](http://www.xtuple.org/xtincident/view/bugs/23894) 
-  _Support install of third-party extensions using npm_ 
-- Implemented 
-  issue #[23965](http://www.xtuple.org/xtincident/view/bugs/23965) 
-  _dashboards-lite_ 
-
-4.5.0 (Beta 2014/05/22, Final 2014/06/06)
-==================
-
-Critical deployment changes
----------------------------
-- If you installed 4.5.0 beta on your database, and want to upgrade it from the beta
-  to 4.5.0 final, you'll need to update the column type of the `taxpay.taxpay_id`
-  column from `integer` to `serial`.
-
-  If you're going straight to 4.5 final, you don't have to worry about this.
-
-  In general, of course, it's best not to put your production database through a beta.
-  You can pilot on a beta, but then to get to the final, you should pilot straight
-  from your production version to the final.
-
-
-Features and bugfixes
----------------------
-- Implemented 
-  issue #[23243](http://www.xtuple.org/xtincident/view/bugs/23243) 
-  _unified build: bring in xwd_ 
-- Fixed 
-  issue #[23279](http://www.xtuple.org/xtincident/view/bugs/23279) 
-  _Can't open order on issue to shipping screen_ 
-- Fixed 
-  issue #[23411](http://www.xtuple.org/xtincident/view/bugs/23411) 
-  _Need a way to set Base Currency_ 
-- Fixed 
-  issue #[23559](http://www.xtuple.org/xtincident/view/bugs/23559) 
-  _Syntax error on Sales Orders_ 
-- Fixed 
-  issue #[23588](http://www.xtuple.org/xtincident/view/bugs/23588) 
-  _Item on Sales Order copies irrelevantly_ 
-- Fixed 
-  issue #[23602](http://www.xtuple.org/xtincident/view/bugs/23602) 
-  _Rescheduling Sales Order does not reschedule all lines_ 
-- Fixed 
-  issue #[23607](http://www.xtuple.org/xtincident/view/bugs/23607) 
-  _Description cut off on item site widget_ 
-- Fixed 
-  issue #[23649](http://www.xtuple.org/xtincident/view/bugs/23649) 
-  _Filters on Work Orders do not work_ 
-- Fixed 
-  issue #[23760](http://www.xtuple.org/xtincident/view/bugs/23760) 
-  _error in itemsite list_ 
-
-4.4.1 (2014/05/09)
-==================
-
-Features and bugfixes
----------------------
-- Fixed 
-  issue #[21728](http://www.xtuple.org/xtincident/view/bugs/21728) 
-  _Worksheet (Timesheet) sets rate to 0 on Expense line when Billable unchecked_ 
-- Fixed 
-  issue #[21973](http://www.xtuple.org/xtincident/view/bugs/21973) 
-  _Web client does not work on IE 11_ 
-- Fixed 
-  issue #[23111](http://www.xtuple.org/xtincident/view/bugs/23111) 
-  _Time Expense settings on tasks missing_ 
-- Implemented 
-  issue #[23165](http://www.xtuple.org/xtincident/view/bugs/23165) 
-  _Apply XT.Data buildClause refactor to three implementations_ 
-- Fixed 
-  issue #[23234](http://www.xtuple.org/xtincident/view/bugs/23234) 
-  _Can not enter work sheets without view items privilege_ 
-- Implemented 
-  issue #[23241](http://www.xtuple.org/xtincident/view/bugs/23241) 
-  _Unified build: get data to match in commercial databases_ 
-- Implemented 
-  issue #[23242](http://www.xtuple.org/xtincident/view/bugs/23242) 
-  _unified build: build reports, uiforms, metasql, etc._ 
-- Fixed 
-  issue #[23250](http://www.xtuple.org/xtincident/view/bugs/23250) 
-  _Can not enter a worksheet without unit privileges_ 
-- Fixed 
-  issue #[23323](http://www.xtuple.org/xtincident/view/bugs/23323) 
-  _Errors on search_ 
-- Implemented 
-  issue #[23340](http://www.xtuple.org/xtincident/view/bugs/23340) 
-  _Unified build: move in reports_ 
-- Implemented 
-  issue #[23357](http://www.xtuple.org/xtincident/view/bugs/23357) 
-  _unified build: standard and mfg dbscripts need not be frozen_ 
-- Implemented 
-  issue #[23359](http://www.xtuple.org/xtincident/view/bugs/23359) 
-  _production windows vagrant dry run_ 
-- Fixed 
-  issue #[23370](http://www.xtuple.org/xtincident/view/bugs/23370) 
-  _Can not open documents after "Apply" clicked_ 
-- Fixed 
-  issue #[23402](http://www.xtuple.org/xtincident/view/bugs/23402) 
-  _Cannot create some New things in Empty Database_ 
-- Fixed 
-  issue #[23406](http://www.xtuple.org/xtincident/view/bugs/23406) 
-  _various work order bugs_ 
-- Fixed 
-  issue #[23414](http://www.xtuple.org/xtincident/view/bugs/23414) 
-  _Installing Inventory throws error_ 
-- Fixed 
-  issue #[23560](http://www.xtuple.org/xtincident/view/bugs/23560) 
-  _Sales Order Line items do not default to header site_ 
-- Fixed 
-  issue #[23597](http://www.xtuple.org/xtincident/view/bugs/23597) 
-  _Lazy load does not work on Inventory Availability_ 
-
-
-4.4.0 (2014/04/04)
-==================
-
-Critical deployment changes
----------------------------
-- The `oauth2` extension is now part of core. If you had its routes referenced
-  in your `config.js`'s `extensionRoutes` attribute, you should remove it.
-- Make sure you `git submodule update --init --recursive`
-
-Features and bugfixes
----------------------
-- Completed 
-  issue #[22131](http://www.xtuple.org/xtincident/view/bugs/22131) 
-  _Drilldown support in analytic charts_ 
-- Implemented 
-  issue #[22656](http://www.xtuple.org/xtincident/view/bugs/22656) 
-  _Refactor panels and change visual presentation_ 
-- Fixed 
-  issue #[23012](http://www.xtuple.org/xtincident/view/bugs/23012) 
-  _Roles don't pull in translations_ 
-- Fixed 
-  issue #[23028](http://www.xtuple.org/xtincident/view/bugs/23028) 
-  _install_bi.sh NEEDS path to config file option_ 
-- Implemented 
-  issue #[23046](http://www.xtuple.org/xtincident/view/bugs/23046) 
-  _Update MW to create dynamic class id for enyo list items_ 
-- Implemented 
-  issue #[23086](http://www.xtuple.org/xtincident/view/bugs/23086) 
-  _Unified database build_ 
-- Fixed 
-  issue #[23094](http://www.xtuple.org/xtincident/view/bugs/23094) 
-  _Name/Date Overlap on Sales Order_ 
-- Implemented 
-  issue #[23108](http://www.xtuple.org/xtincident/view/bugs/23108) 
-  _Optimize XT.Data's buildClause to use joins on underlying tables and views_ 
-- Implemented 
-  issue #[23168](http://www.xtuple.org/xtincident/view/bugs/23168) 
-  _move OAUTH2 extension to core_ 
-- Fixed 
-  issue #[23183](http://www.xtuple.org/xtincident/view/bugs/23183) 
-  _*Converting sales order_ 
-- Fixed 
-  issue #[23260](http://www.xtuple.org/xtincident/view/bugs/23260) 
-  _Converting Quote to SO does not work_ 
-
-
-
-1.8.1 (2014/03/12)
-==================
-
-Features and bugfixes
----------------------
-- Fixed 
-  issue #[22518](http://www.xtuple.org/xtincident/view/bugs/22518) 
-  _Post Production, Issue Materials, Enter Receipt, Post Receipt should update workflows_ 
-- Fixed 
-  issue #[22526](http://www.xtuple.org/xtincident/view/bugs/22526) 
-  _Add support to return materials from a Work Order_ 
-- Fixed 
-  issue #[22668](http://www.xtuple.org/xtincident/view/bugs/22668) 
-  _Can not save filters in mobile_ 
-- Fixed 
-  issue #[22746](http://www.xtuple.org/xtincident/view/bugs/22746) 
-  _Long project descriptions bleed into adjacent columns_ 
-- Implemented 
-  issue #[22782](http://www.xtuple.org/xtincident/view/bugs/22782) 
-  _Print pack list_ 
-- Fixed 
-  issue #[22901](http://www.xtuple.org/xtincident/view/bugs/22901) 
-  _Incident plus versions are not showing up_ 
-- Fixed 
-  issue #[23010](http://www.xtuple.org/xtincident/view/bugs/23010) 
-  _Sales Type workflow missing defaults_ 
-- Fixed 
-  issue #[23013](http://www.xtuple.org/xtincident/view/bugs/23013) 
-  _Due date does not calculate on Sales Order Worflow_ 
-- Fixed 
-  issue #[23018](http://www.xtuple.org/xtincident/view/bugs/23018) 
-  _Opportunities do not have default Currency_ 
-
-
-1.8.0 (2014/03/07)
-==================
-
-Features and bugfixes
----------------------
- Implemented 
-  issue #[19037](http://www.xtuple.org/xtincident/view/bugs/19037) 
-  _Summary on project_ 
-- Implemented 
-  issue #[21508](http://www.xtuple.org/xtincident/view/bugs/21508) 
-  _Add support for basic Work Order transactions_ 
-- Implemented 
-  issue #[22078](http://www.xtuple.org/xtincident/view/bugs/22078) 
-  _Add support for Backflush on Post Production_ 
-- Implemented 
-  issue #[22079](http://www.xtuple.org/xtincident/view/bugs/22079) 
-  _Add support for Close Work Order on Post Production_ 
-- Implemented 
-  issue #[22237](http://www.xtuple.org/xtincident/view/bugs/22237) 
-  _Add support to print and email Invoices_ 
-- Implemented 
-  issue #[22241](http://www.xtuple.org/xtincident/view/bugs/22241) 
-  _Add support to print barcode Location labels_ 
-- Implemented 
-  issue #[22243](http://www.xtuple.org/xtincident/view/bugs/22243) 
-  _Add support to print Item barcode labels_ 
-- Implemented 
-  issue #[22442](http://www.xtuple.org/xtincident/view/bugs/22442) 
-  _CRM sales pipeline charts for dashboard_ 
-- Implemented 
-  issue #[22459](http://www.xtuple.org/xtincident/view/bugs/22459) 
-  _Barcode capture use-cases_ 
-- Implemented 
-  issue #[22461](http://www.xtuple.org/xtincident/view/bugs/22461) 
-  _Silent print from nodejs_ 
-- Implemented 
-  issue #[22534](http://www.xtuple.org/xtincident/view/bugs/22534) 
-  _Add support Inventory Availability to web client_ 
-- Implemented 
-  issue #[22577](http://www.xtuple.org/xtincident/view/bugs/22577) 
-  _Private extensions under test_ 
-- Implemented 
-  issue #[22638](http://www.xtuple.org/xtincident/view/bugs/22638) 
-  _Add inventory availability information to Sales Order_ 
-- Fixed 
-  issue #[22645](http://www.xtuple.org/xtincident/view/bugs/22645) 
-  _Internal server error on dogfood_ 
-- Fixed 
-  issue #[22651](http://www.xtuple.org/xtincident/view/bugs/22651) 
-  _Natural Key Not Found Error on Empty DB_ 
-- Implemented 
-  issue #[22669](http://www.xtuple.org/xtincident/view/bugs/22669) 
-  _Add support for automatic supply order creation on Sales Orders_ 
-- Implemented 
-  issue #[22689](http://www.xtuple.org/xtincident/view/bugs/22689) 
-  _Support for a second jsdoc template_ 
-- Fixed 
-  issue #[22728](http://www.xtuple.org/xtincident/view/bugs/22728) 
-  _*Configure list is blank_ 
-- Implemented 
-  issue #[22750](http://www.xtuple.org/xtincident/view/bugs/22750) 
-  _Add project type to project list_ 
-- Implemented 
-  issue #[22822](http://www.xtuple.org/xtincident/view/bugs/22822) 
-  _Add support to for planned order list_ 
-- Implemented 
-  issue #[22971](http://www.xtuple.org/xtincident/view/bugs/22971) 
-  _Get tutorial up to date_ 
-- Fixed 
-  issue #[22980](http://www.xtuple.org/xtincident/view/bugs/22980) 
-  _Optimizations for K+H database_ 
-
-1.7.2 (2014/02/24)
-==================
-
-Features and bugfixes
----------------------
-- Fixed
-  issue #[22754](http://www.xtuple.org/xtincident/view/bugs/22754)
-  _*DB log error is displayed on selecting to add a Bill of Operation Item for a new item_
-- Fixed
-  issue #[22755](http://www.xtuple.org/xtincident/view/bugs/22755) 
-  _* It is not possible to add a Bill of Material Item to a new item_ 
-- Fixed 
-  issue #[22793](http://www.xtuple.org/xtincident/view/bugs/22793) 
-  _Characteristics not showing up on Customer Workspace_ 
-- Implemented 
-  issue #[22829](http://www.xtuple.org/xtincident/view/bugs/22829) 
-  _Registration via Website appears broken_ 
-- Fixed 
-  issue #[22839](http://www.xtuple.org/xtincident/view/bugs/22839) 
-  _Mobile installation disrupts invoices out of qt_ 
-
-1.7.1 (2014/02/10)
-==================
-
-Features and bugfixes
----------------------
-- Fixed
-  issue #[22659](http://www.xtuple.org/xtincident/view/bugs/22659)
-  _Remove xt.obj inheritance to avoid backup column reordering_
-
-1.7.0 (2014/02/03)
-==================
-
-Features and bugfixes
----------------------
-
-- Implemented
-  issue #[22059](http://www.xtuple.org/xtincident/view/bugs/22059)
-  _Approve for billing and create invoice at time of shipping_
-- Implemented
-  issue #[22029](http://www.xtuple.org/xtincident/view/bugs/22029)
-  _Cash receipt on sales order_
-- Implemented
-  issue #[21229](http://www.xtuple.org/xtincident/view/bugs/21229)
-  _REST - Add support for a count query_
-- Implemented
-  issue #[22029](http://www.xtuple.org/xtincident/view/bugs/22029)
-  _Implement Cash Receipt on Sales Order_
-- Implemented
-  issue #[22059](http://www.xtuple.org/xtincident/view/bugs/22059)
-  _Implement Approve for Billing(select for billing)/Create Invoice at time of Shipping_
-- Implemented
-  issue #[22155](http://www.xtuple.org/xtincident/view/bugs/22155)
-  _Add support for Purchase Order_
-- Fixed
-  issue #[22181](http://www.xtuple.org/xtincident/view/bugs/22181)
-  _*Tax adjustment is not added to the Total Tax of an Invoice_
-- Implemented
-  issue #[22237](http://www.xtuple.org/xtincident/view/bugs/22237)
-  _Add support to print and email Invoices_
-- Implemented
-  issue #[22341](http://www.xtuple.org/xtincident/view/bugs/22341)
-  _Add support for Work Orders_
-- Fixed
-  issue #[22397](http://www.xtuple.org/xtincident/view/bugs/22397)
-  _*Unit Cost and Tax amount values are not displayed in the Invoice Line and Return Line screens_
-- Fixed
-  issue #[22398](http://www.xtuple.org/xtincident/view/bugs/22398)
-  _*Fractional Tax values are rounded in the Sales Order Line/Quote Line screen_
-- Fixed
-  issue #[22402](http://www.xtuple.org/xtincident/view/bugs/22402)
-  _itemIspPrice() requires site_id for markup pricing to to work_
-- Fixed
-  issue #[22436](http://www.xtuple.org/xtincident/view/bugs/22436)
-  _Faulty Transfer Order line item statuses_
-- Implemented
-  issue #[22498](http://www.xtuple.org/xtincident/view/bugs/22498)
-  _build 1.7.0 with 4.3 database_
-- Implemented
-  issue #[22500](http://www.xtuple.org/xtincident/view/bugs/22500)
-  _Barcode prefix/suffix should be configurable_
-- Fixed
-  issue #[22588](http://www.xtuple.org/xtincident/view/bugs/22588)
-  _Customers with Credit Warning gets Credit Hold error message_
-- Fixed
-  issue #[22622](http://www.xtuple.org/xtincident/view/bugs/22622)
-  _Workaround Pentaho roles problem_ 
-
-1.6.0 (2014/01/15)
-==================
-
-Critical deployment changes
----------------------------
-Mobile Client connections to Pentaho are no longer defined by biUrl and biServerUrl in config.js.  They are now defined
-by biServer and printServer.  See the details in:
-
-https://github.com/xtuple/xtuple/wiki/xTuple-Business-Intelligence
-
-Features and bugfixes
----------------------
-
-- Fixed
-  issue #[18338](http://www.xtuple.org/xtincident/view/bugs/18338)
-  _Error running merge contacts in dogfood_
-- Fixed
-  issue #[18401](http://www.xtuple.org/xtincident/view/bugs/18401)
-  _Relation autocompleter menu gets in the way_
-- Fixed
-  issue #[18505](http://www.xtuple.org/xtincident/view/bugs/18505)
-  _Advanced search panel is blank on iPad_
-- Fixed
-  issue #[18521](http://www.xtuple.org/xtincident/view/bugs/18521)
-  _Automatically-added comments have "admin" as the name_
-- Fixed
-  issue #[18635](http://www.xtuple.org/xtincident/view/bugs/18635)
-  _Creating a user account in the mobile client does not create a CRM Account_
-- Implemented
-  issue #[18637](http://www.xtuple.org/xtincident/view/bugs/18637)
-  _Extend "Personal" privilege methodology to any property that can be tied back to a UserAccount ID_
-- Fixed
-  issue #[18640](http://www.xtuple.org/xtincident/view/bugs/18640)
-  _error in CRM Acct Merge_
-- Fixed
-  issue #[18692](http://www.xtuple.org/xtincident/view/bugs/18692)
-  _List Relation Box should be disabled for new records_
-- Fixed
-  issue #[18695](http://www.xtuple.org/xtincident/view/bugs/18695)
-  _Comments don't work on iPad_
-- Fixed
-  issue #[18698](http://www.xtuple.org/xtincident/view/bugs/18698)
-  _iPad sorts strings as numbers_
-- Fixed
-  issue #[18699](http://www.xtuple.org/xtincident/view/bugs/18699)
-classes: "right"  _iPad does not scroll smoothly_
-- Fixed
-  issue #[18707](http://www.xtuple.org/xtincident/view/bugs/18707)
-  _Can't switch databases on iPad_
-- Fixed
-  issue #[18730](http://www.xtuple.org/xtincident/view/bugs/18730)
-  _Task number read only status is erratic_
-- Fixed
-  issue #[18731](http://www.xtuple.org/xtincident/view/bugs/18731)
-  _Address placeholders are not translated_
-- Fixed
-  issue #[18732](http://www.xtuple.org/xtincident/view/bugs/18732)
-  _All postgres users are showing up in user list_
-- Fixed
-  issue #[18769](http://www.xtuple.org/xtincident/view/bugs/18769)
-  _Cookies are not being deleted in any test-cases_
-- Completed
-  issue #[18770](http://www.xtuple.org/xtincident/view/bugs/18770)
-  _Integrate node-router into node-datasource_
-- Fixed
-  issue #[19017](http://www.xtuple.org/xtincident/view/bugs/19017)
-  _*Unable to select the project on selecting to create a new incident in dogfood_
-- Fixed
-  issue #[19199](http://www.xtuple.org/xtincident/view/bugs/19199)
-  _Security on reset password._
-- Implemented
-  issue #[20689](http://www.xtuple.org/xtincident/view/bugs/20689)
-  _Support for Barcode_
-- Implemented
-  issue #[20962](http://www.xtuple.org/xtincident/view/bugs/20962)
-  _Add support to enter Receipt transactions_
-- Implemented
-  issue #[21038](http://www.xtuple.org/xtincident/view/bugs/21038)
-  _Complete Issue to Shipping_
-- Fixed
-  issue #[21476](http://www.xtuple.org/xtincident/view/bugs/21476)
-  _*Unable to select back 'External' option as the Gateway for Credit cards in System Configuration screen_
-- Implemented
-  issue #[21508](http://www.xtuple.org/xtincident/view/bugs/21508)
-  _Add support for basic Work Order transactions_
-- Implemented
-  issue #[21584](http://www.xtuple.org/xtincident/view/bugs/21584)
-  _Organize pentaho properties in config.js_
-- Fixed
-  issue #[21686](http://www.xtuple.org/xtincident/view/bugs/21686)
-  _*Toolbar overlaps the Export icon making it unable to select in mobile devices_
-- Fixed
-  issue #[21889](http://www.xtuple.org/xtincident/view/bugs/21889)
-  _Mobile Web Client List View Items Overlap_
-- Fixed
-  issue #[21909](http://www.xtuple.org/xtincident/view/bugs/21909)
-  _ErpBI configuration not production ready_
-- Fixed
-  issue #[21978](http://www.xtuple.org/xtincident/view/bugs/21978)
-  _Item auto-populates on Sales Order when it should not_
-- Implemented
-  issue #[22059](http://www.xtuple.org/xtincident/view/bugs/22059)
-  _Implement Approve for Billing(select for billing)/Create Invoice at time of Shipping_
-- Implemented
-  issue #[22067](http://www.xtuple.org/xtincident/view/bugs/22067)
-  _Implement returns(credit memo)_
-- Implemented
-  issue #[22072](http://www.xtuple.org/xtincident/view/bugs/22072)
-  _Add support for Transfer Order_
-- Implemented
-  issue #[22129](http://www.xtuple.org/xtincident/view/bugs/22129)
-  _Support system printers for reports_
-- Fixed
-  issue #[22151](http://www.xtuple.org/xtincident/view/bugs/22151)
-  _Selecting ITEM-GROUP produces internal server error_
-- Fixed
-  issue #[22152](http://www.xtuple.org/xtincident/view/bugs/22152)
-  _Site is required in PostBooks_
-- Fixed
-  issue #[22172](http://www.xtuple.org/xtincident/view/bugs/22172)
-  _Item Group does not appear in Postbooks_
-- Implemented
-  issue #[22175](http://www.xtuple.org/xtincident/view/bugs/22175)
-  _Add the ability to issue to shipping and ship from Sales Order_
-- Fixed
-  issue #[22214](http://www.xtuple.org/xtincident/view/bugs/22214)
-  _Inventory gear options not showing on small devices_
-- Fixed
-  issue #[22224](http://www.xtuple.org/xtincident/view/bugs/22224)
-  _*Selecting 'Issue to Shipping' displays a JS console error and does not displays any response_
-- No Change Required
-  issue #[22227](http://www.xtuple.org/xtincident/view/bugs/22227)
-  _*Selecting to open an existing shipment hangs the application_
-- Fixed
-  issue #[22298](http://www.xtuple.org/xtincident/view/bugs/22298)
-  _*Selecting to add an address to a record displays an irrelevant dialog_
-- Implemented
-  issue #[22313](http://www.xtuple.org/xtincident/view/bugs/22313)
-  _Improve dev BI script_
-- Fixed
-  issue #[22368](http://www.xtuple.org/xtincident/view/bugs/22368)
-  _*Date format is displayed incorrectly in Transfer order list and Issue to shipping screens_
-- Fixed
-  issue #[22407](http://www.xtuple.org/xtincident/view/bugs/22407)
-  _*Selecting 'Issue to Shipping' without saving the Sales order and then selecting 'Save', doesn't populate the Sales order number_
-- Fixed
-  issue #[22408](http://www.xtuple.org/xtincident/view/bugs/22408)
-  _*Selecting Express Checkout without saving the Sales order and then selecting 'No' in the confirmation dialog displays a console_
-
-1.5.2 (2014/01/13)
-===============
-
-Features and bugfixes
----------------------
-
-- Fixed
-  issue #[22394](http://www.xtuple.org/xtincident/view/bugs/22394)
-  _Context queries can have punishingly slow performance_
-
-1.5.1 (2013/12/04)
-===============
-
-Critical deployment changes
----------------------------
-* File moved xtuple/test/shared/login_data.js -> xtuple/test/lib/login_data.js
-  `mv test/shared/login_data.js test/lib`
-* File moved xtuple/test/mocha/lib/demo-test.backup -> xtuple/test/lib/demo-test.backup
-  `mv test/mocha/lib/demo-test.backup test/lib`
-* If you have inventory registered you will have to change its location
-  `update xt.ext set ext_location = '/private-extensions' where ext_name = 'inventory'`
-
-Features and bugfixes
----------------------
-
-- Implemented
-  issue #[21224](http://www.xtuple.org/xtincident/view/bugs/21224)
-  _REST - Add support for a query "operator" to the REST API and Discovery Docs_
-- Implemented
-  issue #[21587](http://www.xtuple.org/xtincident/view/bugs/21587)
-  _Add Billing configuration_
-- Implemented
-  issue #[21625](http://www.xtuple.org/xtincident/view/bugs/21625)
-  _Implement Reason Code_
-- Fixed
-  issue #[21757](http://www.xtuple.org/xtincident/view/bugs/21757)
-  _Add Project Type to Project_
-- Fixed
-  issue #[21866](http://www.xtuple.org/xtincident/view/bugs/21866)
-  _Cost in Time Sheet (Worksheet) is null when entered through mobile_
-- Fixed
-  issue #[21979](http://www.xtuple.org/xtincident/view/bugs/21979)
-  _Arrowing up down through grid entry to not commit edited value to the model_
-- Implemented
-  issue #[21982](http://www.xtuple.org/xtincident/view/bugs/21982)
-  _Print invoices_
-- Implemented
-  issue #[21986](http://www.xtuple.org/xtincident/view/bugs/21986)
-  _Add support for Workflow to Sales Orders_
-- Implemented
-  issue #[21989](http://www.xtuple.org/xtincident/view/bugs/21989)
-  _Add support on item relation widget to search barcode and alias_
-- Implemented
-  issue #[21992](http://www.xtuple.org/xtincident/view/bugs/21992)
-  _Move inventory to the private-extensions repository_
-- Fixed
-  issue #[22031](http://www.xtuple.org/xtincident/view/bugs/22031)
-  _Can not change settings_
-- Completed
-  issue #[22049](http://www.xtuple.org/xtincident/view/bugs/22049)
-  _Cleanup the test folder_
-- Fixed
-  issue #[22063](http://www.xtuple.org/xtincident/view/bugs/22063)
-  _*Selecting to assign a privilege to a user account role displays 'Internal Server Error' dialog_
-- Fixed
-  issue #[22093](http://www.xtuple.org/xtincident/view/bugs/22093)
-  _View Characteristics disabled still allows Characteristics to be viewed_
-- Fixed
-  issue #[22094](http://www.xtuple.org/xtincident/view/bugs/22094)
-  _Characteristic Privilege declared by the CRM extension error_
-- Fixed
-  issue #[22098](http://www.xtuple.org/xtincident/view/bugs/22098)
-  _Disabled ViewClassCodes priv still allows user to view Class Code_
-- Fixed
-  issue #[22100](http://www.xtuple.org/xtincident/view/bugs/22100)
-  _Disable ViewCostCategory Priv still allows user to view Cost Category_
-- Fixed
-  issue #[22101](http://www.xtuple.org/xtincident/view/bugs/22101)
-  _Cost Category Privs not declared by extensions_
-- Fixed
-  issue #[22102](http://www.xtuple.org/xtincident/view/bugs/22102)
-  _MaintainClassCodes priv not declared by the project extension_
-- Fixed
-  issue #[22103](http://www.xtuple.org/xtincident/view/bugs/22103)
-  _Billing extension will not load without Sales_
-- Fixed
-  issue #[22104](http://www.xtuple.org/xtincident/view/bugs/22104)
-  _Incident Plus will not load without Project_
-- Fixed
-  issue #[22138](http://www.xtuple.org/xtincident/view/bugs/22138)
-  _Save on incident fails_
-- Fixed
-  issue #[22143](http://www.xtuple.org/xtincident/view/bugs/22143)
-  _Agent is required for New User Account_
-- Fixed
-  issue #[22166](http://www.xtuple.org/xtincident/view/bugs/22166)
-  _incident list color is all white_
-
-1.5.0 (2013/11/19)
-==================
-
-Features and bugfixes
----------------------
-
-- Implemented
-  issue #[18917](http://www.xtuple.org/xtincident/view/bugs/18917)
-  _Complete translation functionality_
-- Fixed
-  issue #[19681](http://www.xtuple.org/xtincident/view/bugs/19681)
-  _*Omnibus :It is not possible to re-attach a newly created and detached To Do item from a record_
-- Implemented
-  issue #[20438](http://www.xtuple.org/xtincident/view/bugs/20438)
-  _convert a quote to a sales order_
-- Fixed
-  issue #[20625](http://www.xtuple.org/xtincident/view/bugs/20625)
-  _Customer hold privileges are not enforced on Sales Order_
-- Implemented
-  issue #[20946](http://www.xtuple.org/xtincident/view/bugs/20946)
-  _implement rjson for basic compression_
-- Implemented
-  issue #[21038](http://www.xtuple.org/xtincident/view/bugs/21038)
-  _Complete Issue to Shipping_
-- Implemented
-  issue #[21100](http://www.xtuple.org/xtincident/view/bugs/21100)
-  _Sales Order Line Items should have a border to show_
-- Fixed
-  issue #[21166](http://www.xtuple.org/xtincident/view/bugs/21166)
-  _*Selecting to create a New To Do from the To Do tab of an incident generates a JS console error_
-- Fixed
-  issue #[21178](http://www.xtuple.org/xtincident/view/bugs/21178)
-  _*It is possible to delete the tasks to which Actual Time/Expenses are posted already_
-- Fixed
-  issue #[21245](http://www.xtuple.org/xtincident/view/bugs/21245)
-  _*Inactive Sales representatives are available for selection_
-- Fixed
-  issue #[21442](http://www.xtuple.org/xtincident/view/bugs/21442)
-  _Site Defaults in Mobile Web are not honoring user defaults_
-- Fixed
-  issue #[21448](http://www.xtuple.org/xtincident/view/bugs/21448)
-  _Error checking on functions is spotty in Mobile_
-- Fixed
-  issue #[21483](http://www.xtuple.org/xtincident/view/bugs/21483)
-  _*Omnibus: Records lists doesn't honor the selected 'Sort By' options_
-- Fixed
-  issue #[21491](http://www.xtuple.org/xtincident/view/bugs/21491)
-  _*Selecting to save a new To do item with an incident/Opportunity attached to it displays JS console error_
-- Fixed
-  issue #[21494](http://www.xtuple.org/xtincident/view/bugs/21494)
-  _The Alter Transaction Dates Privilege is not enforced on Issue to Shipping and Ship_
-- Fixed
-  issue #[21529](http://www.xtuple.org/xtincident/view/bugs/21529)
-  _Item Site is incomplete_
-- Implemented
-  issue #[21585](http://www.xtuple.org/xtincident/view/bugs/21585)
-  _Add support for Sales Categories_
-- Implemented
-  issue #[21587](http://www.xtuple.org/xtincident/view/bugs/21587)
-  _Add Billing configuration_
-- Implemented
-  issue #[21601](http://www.xtuple.org/xtincident/view/bugs/21601)
-  _Add mult-select support to worksheets_
-- Fixed
-  issue #[21604](http://www.xtuple.org/xtincident/view/bugs/21604)
-  _Terms implementation is incomplete_
-- Implemented
-  issue #[21614](http://www.xtuple.org/xtincident/view/bugs/21614)
-  _Implement Bank Account_
-- Fixed
-  issue #[21617](http://www.xtuple.org/xtincident/view/bugs/21617)
-  _*Unable to scroll the Time Sheets List in a new Worksheet_
-- Implemented
-  issue #[21625](http://www.xtuple.org/xtincident/view/bugs/21625)
-  _Implement Reason Code_
-- Fixed
-  issue #[21633](http://www.xtuple.org/xtincident/view/bugs/21633)
-  _*Unable to delete a Sales order_
-- Fixed
-  issue #[21650](http://www.xtuple.org/xtincident/view/bugs/21650)
-  _*'Ship' button is active in the Issue to Shipping screen when 'Ship Orders' privilege is disabled for the user_
-- Fixed
-  issue #[21657](http://www.xtuple.org/xtincident/view/bugs/21657)
-  _Grid row doesn't refresh_
-- Fixed
-  issue #[21659](http://www.xtuple.org/xtincident/view/bugs/21659)
-  _Mobile Timecard entry... remembering fields so don't need to continually enter same data_
-- Fixed
-  issue #[21666](http://www.xtuple.org/xtincident/view/bugs/21666)
-  _*Unable to delete a Prospect_
-- Fixed
-  issue #[21667](http://www.xtuple.org/xtincident/view/bugs/21667)
-  _*Unable to delete a Customer_
-- Fixed
-  issue #[21670](http://www.xtuple.org/xtincident/view/bugs/21670)
-  _*Selecting to discard the changes of a Worksheet hangs the application_
-- Implemented
-  issue #[21679](http://www.xtuple.org/xtincident/view/bugs/21679)
-  _Tweak MW refresh icon_
-- Fixed
-  issue #[21680](http://www.xtuple.org/xtincident/view/bugs/21680)
-  _Timesheets in Mobile Web Client Default to Billable, when Customer is Selected_
-- Implemented
-  issue #[21684](http://www.xtuple.org/xtincident/view/bugs/21684)
-  _Implement Invoices_
-- Fixed
-  issue #[21704](http://www.xtuple.org/xtincident/view/bugs/21704)
-  _Unable to use Sales Analysis due to Blocked page_
-- Implemented
-  issue #[21739](http://www.xtuple.org/xtincident/view/bugs/21739)
-  _Projects should support characteristics_
-- Implemented
-  issue #[21750](http://www.xtuple.org/xtincident/view/bugs/21750)
-  _Develop OLAP client support for dashboards_
-- Implemented
-  issue #[21762](http://www.xtuple.org/xtincident/view/bugs/21762)
-  _Add support for grid entry to project_
-- Fixed
-  issue #[21801](http://www.xtuple.org/xtincident/view/bugs/21801)
-  _xt error on desktop 4.1  with Mobile client_
-- Implemented
-  issue #[21807](http://www.xtuple.org/xtincident/view/bugs/21807)
-  _Develop install script for Pentaho_
-- Implemented
-  issue #[21821](http://www.xtuple.org/xtincident/view/bugs/21821)
-  _Need new welcome screen metric for MW_
-- Fixed
-  issue #[21831](http://www.xtuple.org/xtincident/view/bugs/21831)
-  _Can not run xt-mobile scripts on db upgraded from 4.1.0 to 4.2.0_
-- Implemented
-  issue #[21834](http://www.xtuple.org/xtincident/view/bugs/21834)
-  _Prerequisite Checks for Mobile Required_
-- Fixed
-  issue #[21851](http://www.xtuple.org/xtincident/view/bugs/21851)
-  _mobile no longer uses bindAddress_
-- Implemented
-  issue #[21864](http://www.xtuple.org/xtincident/view/bugs/21864)
-  _assign project tasks to resources_
-- Fixed
-  issue #[21894](http://www.xtuple.org/xtincident/view/bugs/21894)
-  _Address can not be updated_
-- Implemented
-  issue #[21895](http://www.xtuple.org/xtincident/view/bugs/21895)
-  _Initial analytic charts for dashboard in Sales BI Extension_
-- Fixed
-  issue #[21933](http://www.xtuple.org/xtincident/view/bugs/21933)
-  _Client not responding after log in_
-- Fixed
-  issue #[21994](http://www.xtuple.org/xtincident/view/bugs/21994)
-  _*Selecting to run the install script displays Syntax error_
-
-This version requires version 4.2.0 or higher of xTuple PostBooks or commercial edition database.
-
-1.4.6 (2013/11/xx)
-==================
-Critical deployment changes
----------------------------
-- The Sales Dashboard has been redesigned to show sales data from analytic cubes.  To connect to the BI Server
-you must define:
-
-   biServer: {
-        hostname: "localhost",
-        port: 8080,
-        catalog: "xTuple",
-        tenantname: "default",
-        keyFile: "./lib/rest-keys/server.key"
-      }
-in config.js.  Also, the Sales Dashboard is now structured in a private extension:
-
-   https://github.com/xtuple/private-extensions/tree/master/source/bi
-
-1.4.5 (2013/10/11)
-==================
-
-Features and bugfixes
----------------------
-
-- Fixed
-  issue #[19869](http://www.xtuple.org/xtincident/view/bugs/19869)
-  _*Omnibus: Locked record is displayed on selecting to open a contact after discarding new contact screen opened from it _
-- Fixed
-  issue #[19957](http://www.xtuple.org/xtincident/view/bugs/19957)
-  _Selecting to create a new Customer/Prospect from the customer field of Quote screen doesn't populates the customer automatically_
-- Fixed
-  issue #[20000](http://www.xtuple.org/xtincident/view/bugs/20000)
-  _* It is not possible to delete the customer SHIP-TO on reopening the customer_
-- Fixed
-  issue #[20012](http://www.xtuple.org/xtincident/view/bugs/20012)
-  _*Selected sales representative commission rate is not displayed automatically on the Customer screen_
-- Fixed
-  issue #[20064](http://www.xtuple.org/xtincident/view/bugs/20064)
-  _*Ship-To Number search screen is not labeled_
-- Fixed
-  issue #[20071](http://www.xtuple.org/xtincident/view/bugs/20071)
-  _Saving while Customer Ship-To is open gives error then causes other issues_
-- Fixed
-  issue #[20173](http://www.xtuple.org/xtincident/view/bugs/20173)
-  _*It is not possible to assign a Tax Authority to a Tax Code_
-- Fixed
-  issue #[20196](http://www.xtuple.org/xtincident/view/bugs/20196)
-  _*Data Source error is displayed on selecting to search the item sites screen with 'Class Code' filter_
-- Duplicate
-  issue #[20198](http://www.xtuple.org/xtincident/view/bugs/20198)
-  _*'Mask' and 'Validator' fields present under characteristic of type 'Text' are not functional_
-- Implemented
-  issue #[20311](http://www.xtuple.org/xtincident/view/bugs/20311)
-  _Welcome screen iframe does not scroll on iOS devices. CSS fix attached. ASM#5469_
-- Reopened
-  issue #[20332](http://www.xtuple.org/xtincident/view/bugs/20332)
-  _Error Adding a Sales Order to an Opportunity_
-- Implemented
-  issue #[20682](http://www.xtuple.org/xtincident/view/bugs/20682)
-  _Inventory History Report_
-- No Change Required
-  issue #[20885](http://www.xtuple.org/xtincident/view/bugs/20885)
-  _Time Expense Version has Incorrect title_
-- Fixed
-  issue #[20888](http://www.xtuple.org/xtincident/view/bugs/20888)
-  _Class Code List updates after a Discard_
-- Fixed
-  issue #[20981](http://www.xtuple.org/xtincident/view/bugs/20981)
-  _BI Readme steps updated_
-- Fixed
-  issue #[20994](http://www.xtuple.org/xtincident/view/bugs/20994)
-  _Clicking on Advanced Search displays History_
-- Fixed
-  issue #[21008](http://www.xtuple.org/xtincident/view/bugs/21008)
-  _*CRM Dashboard charts are duplicated on selecting to refresh_
-- Fixed
-  issue #[21062](http://www.xtuple.org/xtincident/view/bugs/21062)
-  _Using Help Pullout Tab gives Java Console Error_
-- Fixed
-  issue #[21110](http://www.xtuple.org/xtincident/view/bugs/21110)
-  _*Omnibus: Record is locked for some time on selecting 'Save and New' or 'New' button from the record screen_
-- Fixed
-  issue #[21114](http://www.xtuple.org/xtincident/view/bugs/21114)
-  _*observation: Unable to delete a Sales Representative_
-- Fixed
-  issue #[21181](http://www.xtuple.org/xtincident/view/bugs/21181)
-  _*New Quotes/Sales Orders created from the Opportunity screen are not displayed as attached to the Opportunity_
-- Fixed
-  issue #[21182](http://www.xtuple.org/xtincident/view/bugs/21182)
-  _*Omnibus: Selecting to delete a characteristic and save the record displays irrelevant dialog_
-- Fixed
-  issue #[21230](http://www.xtuple.org/xtincident/view/bugs/21230)
-  _*Employee screen doesn't save the Group attached to it_
-- Fixed
-  issue #[21232](http://www.xtuple.org/xtincident/view/bugs/21232)
-  _*Translation is required for the description label in the 'Advanced Search' panel of Employee Group list_
-- Duplicate
-  issue #[21248](http://www.xtuple.org/xtincident/view/bugs/21248)
-  _* Translation is required for the timeExpense label in About screen_
-- Fixed
-  issue #[21270](http://www.xtuple.org/xtincident/view/bugs/21270)
-  _*Translation is required for the  label in About screen_
-- Fixed
-  issue #[21383](http://www.xtuple.org/xtincident/view/bugs/21383)
-  _Found/Fixed in lists are not populated on Advanced Search_
-- Fixed
-  issue #[21396](http://www.xtuple.org/xtincident/view/bugs/21396)
-  _Misbehavior in Time/Expense editor panels_
-- Fixed
-  issue #[21401](http://www.xtuple.org/xtincident/view/bugs/21401)
-  _Gear on worksheet list inconsistent_
-- Fixed
-  issue #[21402](http://www.xtuple.org/xtincident/view/bugs/21402)
-  _All new records prompt to discard on iPad_
-- No Change Required
-  issue #[21415](http://www.xtuple.org/xtincident/view/bugs/21415)
-  _Attaching an Incident or Contact to an Account will not save_
-- Fixed
-  issue #[21419](http://www.xtuple.org/xtincident/view/bugs/21419)
-  _Worksheet owned by person who created it_
-- Fixed
-  issue #[21425](http://www.xtuple.org/xtincident/view/bugs/21425)
-  _List box editor doesn't validate_
-- Fixed
-  issue #[21437](http://www.xtuple.org/xtincident/view/bugs/21437)
-  _Pickers not populating on configuration_
-- Fixed
-  issue #[21440](http://www.xtuple.org/xtincident/view/bugs/21440)
-  _*Delete option is inactive for Tax Authorities_
-- Fixed
-  issue #[21451](http://www.xtuple.org/xtincident/view/bugs/21451)
-  _Timesheet remembers my location every time_
-- Fixed
-  issue #[21454](http://www.xtuple.org/xtincident/view/bugs/21454)
-  _Search box pushed off the screen_
-- Fixed
-  issue #[21473](http://www.xtuple.org/xtincident/view/bugs/21473)
-  _Unable to login Standard if Inventory or Sales is not enabled_
-- Fixed
-  issue #[21479](http://www.xtuple.org/xtincident/view/bugs/21479)
-  _*'View Inventory History' privilege under 'Inventory' module requires translation_
-- Fixed
-  issue #[21480](http://www.xtuple.org/xtincident/view/bugs/21480)
-  _*Transaction Date, Transaction Type and Order Type options in the Sort By list of 'Inventory History' require translation_
-- Implemented
-  issue #[21487](http://www.xtuple.org/xtincident/view/bugs/21487)
-  _grid entry in quote_
-- Fixed
-  issue #[21496](http://www.xtuple.org/xtincident/view/bugs/21496)
-  _*It is possible to select a project in 'Complete' status to create a time/expense sheet_
-- Fixed
-  issue #[21500](http://www.xtuple.org/xtincident/view/bugs/21500)
-  _Icons on pickers overlap text when scrolling_
-- Fixed
-  issue #[21505](http://www.xtuple.org/xtincident/view/bugs/21505)
-  _Mobile object names inconsistent with precedent_
-- Fixed
-  issue #[21515](http://www.xtuple.org/xtincident/view/bugs/21515)
-  _*Incorrect Project Task is displayed in the Time/Expense sheet of a worksheet_
-- Fixed
-  issue #[21540](http://www.xtuple.org/xtincident/view/bugs/21540)
-  _Characteristics don't get disabled_
-- Fixed
-  issue #[21541](http://www.xtuple.org/xtincident/view/bugs/21541)
-  _*Unable to update the Schedule date of a Quote_
-- Fixed
-  issue #[21565](http://www.xtuple.org/xtincident/view/bugs/21565)
-  _Selecting new time entry brings up prior entry_
-- Implemented
-  issue #[21581](http://www.xtuple.org/xtincident/view/bugs/21581)
-  _Add freight class picker to item workspace_
-- Fixed
-  issue #[21605](http://www.xtuple.org/xtincident/view/bugs/21605)
-  _Document linkages are only showing up on one side_
-- Fixed
-  issue #[21627](http://www.xtuple.org/xtincident/view/bugs/21627)
-  _Sales analysis (and other) object name problem_
-
-
-1.4.4 (2013/09/27)
-==================
-
-Features and bugfixes
----------------------
-
-- Implemented
-  issue #[18833](http://www.xtuple.org/xtincident/view/bugs/18833)
-  _Would like user customizable content on lists_
-- Implemented
-  issue #[19647](http://www.xtuple.org/xtincident/view/bugs/19647)
-  _Report dates and currency must be localizable_
-- Fixed
-  issue #[19858](http://www.xtuple.org/xtincident/view/bugs/19858)
-  _*Unable to delete a Project Task from Project Tasks screen_
-- Fixed
-  issue #[20449](http://www.xtuple.org/xtincident/view/bugs/20449)
-  _Incidents gives error when CRM is only extension_
-- Implemented
-  issue #[20677](http://www.xtuple.org/xtincident/view/bugs/20677)
-  _Create Location object_
-- Implemented
-  issue #[20683](http://www.xtuple.org/xtincident/view/bugs/20683)
-  _Backlog Report_
-- Implemented
-  issue #[20684](http://www.xtuple.org/xtincident/view/bugs/20684)
-  _Create Shipments List object and views with return action_
-- Implemented
-  issue #[20734](http://www.xtuple.org/xtincident/view/bugs/20734)
-  _Issue to Shipping_
-- Fixed
-  issue #[20800](http://www.xtuple.org/xtincident/view/bugs/20800)
-  _*Delete option is active for contacts attached to ToDoitem/Opportunity_
-- Fixed
-  issue #[20927](http://www.xtuple.org/xtincident/view/bugs/20927)
-  _Install script says finished when it is not_
-- Fixed
-  issue #[20954](http://www.xtuple.org/xtincident/view/bugs/20954)
-  _Problems in report data from data-from-key_
-- Fixed
-  issue #[21093](http://www.xtuple.org/xtincident/view/bugs/21093)
-  _*No error message is displayed on selecting to delete an item with item site created for it_
-- Fixed
-  issue #[21176](http://www.xtuple.org/xtincident/view/bugs/21176)
-  _*Unable to save comments for a To do item_
-- Fixed
-  issue #[21189](http://www.xtuple.org/xtincident/view/bugs/21189)
-  _Files over 1MB does not appear to complete upload_
-- Implemented
-  issue #[21251](http://www.xtuple.org/xtincident/view/bugs/21251)
-  _Add credit card processing support to Sales Order_
-- Fixed
-  issue #[21277](http://www.xtuple.org/xtincident/view/bugs/21277)
-  _T/E mobile not enforcing view other rules._
-- Fixed
-  issue #[21306](http://www.xtuple.org/xtincident/view/bugs/21306)
-  _Menu presentation order unpredictable_
-- Fixed
-  issue #[21316](http://www.xtuple.org/xtincident/view/bugs/21316)
-  _Time and Expense uneditable when unapproved_
-- Completed
-  issue #[21327](http://www.xtuple.org/xtincident/view/bugs/21327)
-  _Sales cubes dimension and measure terminology_
-- Completed
-  issue #[21360](http://www.xtuple.org/xtincident/view/bugs/21360)
-  _add monthly calendar to sales cubes_
-- Completed
-  issue #[21361](http://www.xtuple.org/xtincident/view/bugs/21361)
-  _Should be able to save Sales Analysis query_
-- Fixed
-  issue #[21368](http://www.xtuple.org/xtincident/view/bugs/21368)
-  _Worksheets bring in wrong customer reference_
-- Fixed
-  issue #[21385](http://www.xtuple.org/xtincident/view/bugs/21385)
-  _TE Worksheet List does not filter on on Date_
-- Fixed
-  issue #[21399](http://www.xtuple.org/xtincident/view/bugs/21399)
-  _Can't find worksheet total hours_
-- Fixed
-  issue #[21403](http://www.xtuple.org/xtincident/view/bugs/21403)
-  _Worksheets should default to self as the Employee_
-- Fixed
-  issue #[21407](http://www.xtuple.org/xtincident/view/bugs/21407)
-  _Field missing on Worksheet:  hourly cost_
-- Fixed
-  issue #[21427](http://www.xtuple.org/xtincident/view/bugs/21427)
-  _Inventory Extension adding expense category to setup menu_
-- Fixed
-  issue #[21432](http://www.xtuple.org/xtincident/view/bugs/21432)
-  _forgot password error_
-- Fixed
-  issue #[21439](http://www.xtuple.org/xtincident/view/bugs/21439)
-  _Picker is too wide on money widgets_
-- Fixed
-  issue #[21442](http://www.xtuple.org/xtincident/view/bugs/21442)
-  _Site Defaults in Mobile Web are not honoring user defaults_
-- Fixed
-  issue #[21453](http://www.xtuple.org/xtincident/view/bugs/21453)
-  _Firefox is blocking mobile help content_
-- Fixed
-  issue #[21455](http://www.xtuple.org/xtincident/view/bugs/21455)
-  _Sort is not working for Sort and Layout Attribute Pickers_
-- Fixed
-  issue #[21478](http://www.xtuple.org/xtincident/view/bugs/21478)
-  _*Selecting to create new Shipment record displays insufficient privileges dialog_
-- Fixed
-  issue #[21482](http://www.xtuple.org/xtincident/view/bugs/21482)
-  _*Omnibus: Blank screen is displayed on selecting to print any record/records list_
-- Fixed
-  issue #[21495](http://www.xtuple.org/xtincident/view/bugs/21495)
-  _Cannot Search for Incident Contact_
-- Fixed
-  issue #[21497](http://www.xtuple.org/xtincident/view/bugs/21497)
-  _Time Expense has dependency on Sales_
-- Fixed
-  issue #[21498](http://www.xtuple.org/xtincident/view/bugs/21498)
-  _Users can not save time sheet if no prvilege_
-- Fixed
-  issue #[21524](http://www.xtuple.org/xtincident/view/bugs/21524)
-  _Printing Admin Account causes unhandled Error_
-- Fixed
-  issue #[21532](http://www.xtuple.org/xtincident/view/bugs/21532)
-  _Cannot open an existing Item_
-
-
-1.4.3 (2013/09/11)
-==================
-
-Features and bugfixes
----------------------
-- Implemented
-  issue #[18488](http://www.xtuple.org/xtincident/view/bugs/18488)
-  _Add sort option to Mobile client_
-- Fixed
-  issue #[19395](http://www.xtuple.org/xtincident/view/bugs/19395)
-  _*Unable to delete a contact with no address_
-- Fixed
-  issue #[19680](http://www.xtuple.org/xtincident/view/bugs/19680)
-  _Email profiles are not editable_
-- Fixed
-  issue #[19966](http://www.xtuple.org/xtincident/view/bugs/19966)
-  _*It is possible to create a Quote without any line item_
-- Fixed
-  issue #[19992](http://www.xtuple.org/xtincident/view/bugs/19992)
-  _*New quote created from a Customer does not populates the customer number  automatically in 'Customer' field of quote screen_
-- Fixed
-  issue #[19993](http://www.xtuple.org/xtincident/view/bugs/19993)
-  _*Detach button in the Quotes panel of a customer is not functional_
-- Implemented
-  issue #[20445](http://www.xtuple.org/xtincident/view/bugs/20445)
-  _Login Page should have "Forgot Password" link/functionality_
-- Fixed
-  issue #[20458](http://www.xtuple.org/xtincident/view/bugs/20458)
-  _Editing Worksheet Time Billable does not save_
-- Fixed
-  issue #[20460](http://www.xtuple.org/xtincident/view/bugs/20460)
-  _Posting a Worksheet does not appear to do anything_
-- Implemented
-  issue #[20782](http://www.xtuple.org/xtincident/view/bugs/20782)
-  _add vCard export functionality for contacts_
-- Implemented
-  issue #[20851](http://www.xtuple.org/xtincident/view/bugs/20851)
-  _REST support for field-level queries_
-- Fixed
-  issue #[20909](http://www.xtuple.org/xtincident/view/bugs/20909)
-  _ListRelationsEditorBox fails if you delete an intermediate item_
-- Fixed
-  issue #[20960](http://www.xtuple.org/xtincident/view/bugs/20960)
-  _Cannot create new Site_
-- Fixed
-  issue #[20961](http://www.xtuple.org/xtincident/view/bugs/20961)
-  _Deleting a Site does not work_
-- Completed
-  issue #[20987](http://www.xtuple.org/xtincident/view/bugs/20987)
-  _Pentaho tenant to include server IP_
-- Implemented
-  issue #[21046](http://www.xtuple.org/xtincident/view/bugs/21046)
-  _Add context messaging tools for Mobile Web UI (Sales Analysis)_
-- Fixed
-  issue #[21097](http://www.xtuple.org/xtincident/view/bugs/21097)
-  _*Selecting to edit and save an item site displays irrelevant message_
-- Fixed
-  issue #[21112](http://www.xtuple.org/xtincident/view/bugs/21112)
-  _*Omnibus: Action icon button doesn't respond on clicking when 'Advanced Search' panel is open for the list of records_
-- Fixed
-  issue #[21120](http://www.xtuple.org/xtincident/view/bugs/21120)
-  _*Observation: Selecting to save the Tax rate with currency set to default displays 'currency is required' message irrelevantly_
-- Fixed
-  issue #[21121](http://www.xtuple.org/xtincident/view/bugs/21121)
-  _*Selecting 'Save' in the Tax Rate screen without selecting the Tax Code doesn't displays any error message_
-- Fixed
-  issue #[21123](http://www.xtuple.org/xtincident/view/bugs/21123)
-  _Multi-Site option should not be allowed off if there are Multi-sites_
-- Fixed
-  issue #[21158](http://www.xtuple.org/xtincident/view/bugs/21158)
-  _*translation required for effective and expiry date warning messages_
-- Fixed
-  issue #[21201](http://www.xtuple.org/xtincident/view/bugs/21201)
-  _*Delete option is active for Used contacts_
-- Fixed
-  issue #[21234](http://www.xtuple.org/xtincident/view/bugs/21234)
-  _*It is possible to edit and save the Billing rate currency of the Time And Expense sheets of an Approved worksheet_
-- Fixed
-  issue #[21256](http://www.xtuple.org/xtincident/view/bugs/21256)
-  _Project does not save with filter_
-- Fixed
-  issue #[21276](http://www.xtuple.org/xtincident/view/bugs/21276)
-  _mobile TE scrolling_
-- Fixed
-  issue #[21289](http://www.xtuple.org/xtincident/view/bugs/21289)
-  _A user who only has personal privileges can not create records_
-- Fixed
-  issue #[21302](http://www.xtuple.org/xtincident/view/bugs/21302)
-  _Task assignments not working on worksheets_
-- Fixed
-  issue #[21359](http://www.xtuple.org/xtincident/view/bugs/21359)
-  _Worksheet list unacceptably slow_
-- Fixed
-  issue #[21374](http://www.xtuple.org/xtincident/view/bugs/21374)
-  _Last saved filter doesn't default_
-- Fixed
-  issue #[21375](http://www.xtuple.org/xtincident/view/bugs/21375)
-  _Default search criteria appearing on widget searches_
-- Fixed
-  issue #[21395](http://www.xtuple.org/xtincident/view/bugs/21395)
-  _Selecting worksheets sometimes opens wrong selection_
-
-
-1.4.2 (2013/08/23)
-==================
-
-Features and bugfixes
----------------------
-- Fixed
-  issue #[21260](http://www.xtuple.org/xtincident/view/bugs/21260)
-  _XT.filter table naming conflict with public.filter_
-
-
-1.4.1 (2013/08/21)
-===============
-
-Features and bugfixes
-----------------
-- Implemented
-  issue #[18668](http://www.xtuple.org/xtincident/view/bugs/18668)
-  _Initial documentation build for Mobile platform_
-- Implemented
-  issue #[19294](http://www.xtuple.org/xtincident/view/bugs/19294)
-  _OAuth 2.0 - Refactor route and functor mapping in Express to use a loop for loading_
-- Implemented
-  issue #[19303](http://www.xtuple.org/xtincident/view/bugs/19303)
-  _REST - Add Discovery Service routes_
-- Implemented
-  issue #[19305](http://www.xtuple.org/xtincident/view/bugs/19305)
-  _REST - Add route handler functions for end point CRUD_
-- Implemented
-  issue #[19306](http://www.xtuple.org/xtincident/view/bugs/19306)
-  _REST - Add "service" endpoints_
-- Completed
-  issue #[19443](http://www.xtuple.org/xtincident/view/bugs/19443)
-  _Use data schema in Pentaho report scripts_
-- Fixed
-  issue #[20195](http://www.xtuple.org/xtincident/view/bugs/20195)
-  _*Irrelevant behavior is observed on re-opening a quote_
-- Fixed
-  issue #[20265](http://www.xtuple.org/xtincident/view/bugs/20265)
-  _OAUTH - Existing session/cookie causes client to load. Fix redirect to auth dialog page_
-- Fixed
-  issue #[20458](http://www.xtuple.org/xtincident/view/bugs/20458)
-  _Editing Worksheet Time Billable does not save_
-- Fixed
-  issue #[20642](http://www.xtuple.org/xtincident/view/bugs/20642)
-  _Filters broken on incidents_
-- Implemented
-  issue #[20864](http://www.xtuple.org/xtincident/view/bugs/20864)
-  _Grid entry for Sales Order on Desktop based browser client_
-- Implemented
-  issue #[20866](http://www.xtuple.org/xtincident/view/bugs/20866)
-  _Allow filters to be saved on lists_
-- Fixed
-  issue #[20886](http://www.xtuple.org/xtincident/view/bugs/20886)
-  _Searchable is required on New Characteristic_
-- Implemented
-  issue #[20890](http://www.xtuple.org/xtincident/view/bugs/20890)
-  _OAuth2 - Admin Interface Usability Tweaks_
-- Fixed
-  issue #[20891](http://www.xtuple.org/xtincident/view/bugs/20891)
-  _Add "website" to contact overview_
-- Fixed
-  issue #[20898](http://www.xtuple.org/xtincident/view/bugs/20898)
-  _Item Site not populating correctly for Sales Order_
-- Fixed
-  issue #[20899](http://www.xtuple.org/xtincident/view/bugs/20899)
-  _Advanced Search does not display list after clearing bad data_
-- Fixed
-  issue #[20902](http://www.xtuple.org/xtincident/view/bugs/20902)
-  _Adding an Item to Quote_
-- Fixed
-  issue #[20908](http://www.xtuple.org/xtincident/view/bugs/20908)
-  _Dashboard Charts shrink upon returning to Dashboard screen_
-- Fixed
-  issue #[20932](http://www.xtuple.org/xtincident/view/bugs/20932)
-  _Dashboard Query is not working_
-- Fixed
-  issue #[20979](http://www.xtuple.org/xtincident/view/bugs/20979)
-  _oath2client table entry for Pentaho needs to use default database_
-- Fixed
-  issue #[20983](http://www.xtuple.org/xtincident/view/bugs/20983)
-  _History shows "undefined" for many objects_
-- Fixed
-  issue #[20989](http://www.xtuple.org/xtincident/view/bugs/20989)
-  _oauth2 check for JWT issued in the future causes timing problem_
-- Fixed
-  issue #[21016](http://www.xtuple.org/xtincident/view/bugs/21016)
-  _Cost Categories Desciption alignment is wrong_
-- Fixed
-  issue #[21051](http://www.xtuple.org/xtincident/view/bugs/21051)
-  _Characteristic - No Error message when trying to save without a role_
-- Fixed
-  issue #[21055](http://www.xtuple.org/xtincident/view/bugs/21055)
-  _Updating Extensions on Role will not allow application to load on login_
-- Fixed
-  issue #[21066](http://www.xtuple.org/xtincident/view/bugs/21066)
-  _Editing a Sales Order gives _shipped error_
-- Fixed
-  issue #[21129](http://www.xtuple.org/xtincident/view/bugs/21129)
-  _Sales Analysis user can not use Pentaho single sign on without admin privilege_
-- Fixed
-  issue #[21138](http://www.xtuple.org/xtincident/view/bugs/21138)
-  _Relation Lists are not loading Properly in Workspaces_
-
-
-1.4.0 (2013/08/07)
-===============
-
-Features and bugfixes
-----------------
-- Fixed
-  issue #[18711](http://www.xtuple.org/xtincident/view/bugs/18711)
-  _Edit Owner privilege is not enforced_
-- Fixed
-  issue #[18724](http://www.xtuple.org/xtincident/view/bugs/18724)
-  _ReassignToDoItems privilege is not enforced_
-- Fixed
-  issue #[18726](http://www.xtuple.org/xtincident/view/bugs/18726)
-  _*Left of Contact Address Not Visible in panel_
-- Fixed
-  issue #[18968](http://www.xtuple.org/xtincident/view/bugs/18968)
-  _Panel sizing on Item workspace_
-- Fixed
-  issue #[19042](http://www.xtuple.org/xtincident/view/bugs/19042)
-  _Omnibus: Observation: New User Account created from Owner field is not populated automatically in Owner field_
-- Implemented
-  issue #[19626](http://www.xtuple.org/xtincident/view/bugs/19626)
-  _Add link to google maps_
-- Completed
-  issue #[19645](http://www.xtuple.org/xtincident/view/bugs/19645)
-  _Install/build process for reports_
-- Fixed
-  issue #[19711](http://www.xtuple.org/xtincident/view/bugs/19711)
-  _*Irrelevant behavior is observed on selecting to save the role assigned to the CRM Account_
-- Fixed
-  issue #[19796](http://www.xtuple.org/xtincident/view/bugs/19796)
-  _Quote shows costs when users do not have cost privilege_
-- Fixed
-  issue #[19800](http://www.xtuple.org/xtincident/view/bugs/19800)
-  _Site should only appear on quote when multi-site enabled_
-- Implemented
-  issue #[19801](http://www.xtuple.org/xtincident/view/bugs/19801)
-  _Site should default on quote_
-- Fixed
-  issue #[19805](http://www.xtuple.org/xtincident/view/bugs/19805)
-  _User should not be able to edit quote price unless they have privileges to do so_
-- Fixed
-  issue #[19859](http://www.xtuple.org/xtincident/view/bugs/19859)
-  _*Selecting to create a new project task from an existing project task displays Data source error_
-- Fixed
-  issue #[19967](http://www.xtuple.org/xtincident/view/bugs/19967)
-  _*Irrelevant dialog is displayed on saving a quote_
-- Fixed
-  issue #[20008](http://www.xtuple.org/xtincident/view/bugs/20008)
-  _Converting prospect to customer freezes client_
-- Fixed
-  issue #[20068](http://www.xtuple.org/xtincident/view/bugs/20068)
-  _Click Apply on Customer Groups will Lock the record_
-- Implemented
-  issue #[20190](http://www.xtuple.org/xtincident/view/bugs/20190)
-  _Mobile Client Phone Numbers Should be Clickable_
-- Implemented
-  issue #[20380](http://www.xtuple.org/xtincident/view/bugs/20380)
-  _Sales analysis view_
-- Fixed
-  issue #[20489](http://www.xtuple.org/xtincident/view/bugs/20489)
-  _Item does not display Wholesale Price_
-- Implemented
-  issue #[20524](http://www.xtuple.org/xtincident/view/bugs/20524)
-  _build_database script_
-- Fixed
-  issue #[20555](http://www.xtuple.org/xtincident/view/bugs/20555)
-  _new authentication does not work with pgbouncer_
-- Implemented
-  issue #[20559](http://www.xtuple.org/xtincident/view/bugs/20559)
-  _Need to create an interface to manage Oauth_
-- Implemented
-  issue #[20574](http://www.xtuple.org/xtincident/view/bugs/20574)
-  _sales order should use item and site instead of itemsite_
-- No Change Required
-  issue #[20596](http://www.xtuple.org/xtincident/view/bugs/20596)
-  _Numbers cut off by scroller_
-- Implemented
-  issue #[20614](http://www.xtuple.org/xtincident/view/bugs/20614)
-  _Need an installer methodology for the mobile client and extensions_
-- Fixed
-  issue #[20638](http://www.xtuple.org/xtincident/view/bugs/20638)
-  _Attach option on relation boxes should not display objects already attached to other objects_
-- Fixed
-  issue #[20672](http://www.xtuple.org/xtincident/view/bugs/20672)
-  _Admin Role gives Java Console Error_
-- Fixed
-  issue #[20673](http://www.xtuple.org/xtincident/view/bugs/20673)
-  _User Account gives Disable Export error_
-- Implemented
-  issue #[20676](http://www.xtuple.org/xtincident/view/bugs/20676)
-  _Create Inventory Configuration Settings_
-- Implemented
-  issue #[20715](http://www.xtuple.org/xtincident/view/bugs/20715)
-  _Sales dashboard_
-- Implemented
-  issue #[20723](http://www.xtuple.org/xtincident/view/bugs/20723)
-  _Single signon support for Pentaho_
-- Implemented
-  issue #[20726](http://www.xtuple.org/xtincident/view/bugs/20726)
-  _Support for Pentaho dynamic OLAP cubes based on organization_
-- Fixed
-  issue #[20736](http://www.xtuple.org/xtincident/view/bugs/20736)
-  _xt package pkg tables missing triggers, causing issues loading packages_
-- Implemented
-  issue #[20746](http://www.xtuple.org/xtincident/view/bugs/20746)
-  _Multi-tenant support for Sales cubes_
-- Implemented
-  issue #[20747](http://www.xtuple.org/xtincident/view/bugs/20747)
-  _Multi-tenant support for sales ETL_
-- Fixed
-  issue #[20760](http://www.xtuple.org/xtincident/view/bugs/20760)
-  _*Quantity UOM is not available for selection in SO Line item screen_
-- Implemented
-  issue #[20771](http://www.xtuple.org/xtincident/view/bugs/20771)
-  _generate p12 in oauth generate-key route_
-- No Change Required
-  issue #[20774](http://www.xtuple.org/xtincident/view/bugs/20774)
-  _access user_account REST_
-- Fixed
-  issue #[20775](http://www.xtuple.org/xtincident/view/bugs/20775)
-  _Remove xtbatch schema if not being used by mobile_
-- Implemented
-  issue #[20780](http://www.xtuple.org/xtincident/view/bugs/20780)
-  _improve maven reports deployment_
-- Fixed
-  issue #[20785](http://www.xtuple.org/xtincident/view/bugs/20785)
-  _Change Password does not remove Confirmed Password_
-- Fixed
-  issue #[20792](http://www.xtuple.org/xtincident/view/bugs/20792)
-  _*Username of a User Account is editable_
-- Fixed
-  issue #[20803](http://www.xtuple.org/xtincident/view/bugs/20803)
-  _*Observation: Newly created records are displayed as locked on opening the records immediately after creation_
-- Fixed
-  issue #[20814](http://www.xtuple.org/xtincident/view/bugs/20814)
-  _Cannot save a Sales Order_
-- Implemented
-  issue #[20820](http://www.xtuple.org/xtincident/view/bugs/20820)
-  _REST - Expose all objects needed for basic relation functionality to work_
-- Fixed
-  issue #[20848](http://www.xtuple.org/xtincident/view/bugs/20848)
-  _Advanced Search Groupbox is too wide_
-- Implemented
-  issue #[20865](http://www.xtuple.org/xtincident/view/bugs/20865)
-  _Add dropdown indicator icon to picker_
-- Implemented
-  issue #[20868](http://www.xtuple.org/xtincident/view/bugs/20868)
-  _-k flag for build_app_
-- Implemented
-  issue #[20874](http://www.xtuple.org/xtincident/view/bugs/20874)
-  _Merge time and expense functionality into project_
-- Fixed
-  issue #[20999](http://www.xtuple.org/xtincident/view/bugs/20999)
-  _support build_app with absolute -c path_
-- Fixed
-  issue #[21007](http://www.xtuple.org/xtincident/view/bugs/21007)
-  _Sales Analysis does not display correct Cube after changing databases_
-
-Critical deployment changes
----------------------------
-* We have moved the test folder from the node-datasource directory.
-  You will want to move by hand the two gitignored files in there:
-  demo-test.backup, and login_data.js. Then, you can rmdir the
-  `node-datasource/test` folder and all its subfolders.
-* The init_scripts and the command-line ORM installer are gone.
-  You will have to use /scripts/build_app.js for your installation needs.
-  Run it with the -h flag to see the options.
-* The old tools for building client code (deploy.sh, buildExtensions.sh, build_client.js)
-  are gone. Use /scripts/build_app.js for your client-building needs.
-  Run it with the -h flag to see the options.
-* When you merge from master git will complain that it is not able to delete
-  an enyo directory which has just be deinitialized as a submodule. You will
-  want to delete it by hand. This goes for the xtuple and the private-extensions repos.
-
-
-1.3.9 (2013/06/27)
-==================
-
-Features and bugfixes
-----------------
-- Fixed
-  issue #[18845](http://www.xtuple.org/xtincident/view/bugs/18845)
-  _Status is missing from To Do_
-- Fixed
-  issue #[19271](http://www.xtuple.org/xtincident/view/bugs/19271)
-  _Datasource does not enforce privilege extensions on fetch_
-- Fixed
-  issue #[19272](http://www.xtuple.org/xtincident/view/bugs/19272)
-  _Half-drilldown into deprivileged workspaces_
-- Fixed
-  issue #[19797](http://www.xtuple.org/xtincident/view/bugs/19797)
-  _Quote shows margin when user does not have show margin privilege_
-- Fixed
-  issue #[20074](http://www.xtuple.org/xtincident/view/bugs/20074)
-  _*Irrelevant behavior is observed in Quote line items_
-- Fixed
-  issue #[20204](http://www.xtuple.org/xtincident/view/bugs/20204)
-  _Mobile client unaware of public/private comments_
-- Fixed
-  issue #[20272](http://www.xtuple.org/xtincident/view/bugs/20272)
-  _Relation widget keeps appending parameters_
-- Fixed
-  issue #[20332](http://www.xtuple.org/xtincident/view/bugs/20332)
-  _Error Adding a Sales Order to an Opportunity_
-- Fixed
-  issue #[20333](http://www.xtuple.org/xtincident/view/bugs/20333)
-  _Advanced Seach of Sales Rep on Sales Order does not work correctly_
-- Fixed
-  issue #[20356](http://www.xtuple.org/xtincident/view/bugs/20356)
-  _Calendar still active after date is picked_
-- Implemented
-  issue #[20373](http://www.xtuple.org/xtincident/view/bugs/20373)
-  _Bring back DisableExport_
-- Implemented
-  issue #[20375](http://www.xtuple.org/xtincident/view/bugs/20375)
-  _Bring back priv_group_
-- Fixed
-  issue #[20440](http://www.xtuple.org/xtincident/view/bugs/20440)
-  _Incident Documents double when using Apply_
-- Fixed
-  issue #[20456](http://www.xtuple.org/xtincident/view/bugs/20456)
-  _Clicking on Locked Icon gives Console error_
-- Fixed
-  issue #[20476](http://www.xtuple.org/xtincident/view/bugs/20476)
-  _Tax Assignemnt gives Java Console Error_
-- Fixed
-  issue #[20501](http://www.xtuple.org/xtincident/view/bugs/20501)
-  _ToDo and Prospect form report routes_
-- Fixed
-  issue #[20506](http://www.xtuple.org/xtincident/view/bugs/20506)
-  _Add multi-tenant support for Pentaho reports_
-- Fixed
-  issue #[20540](http://www.xtuple.org/xtincident/view/bugs/20540)
-  _User Account Roles do not use groups_
-- Fixed
-  issue #[20549](http://www.xtuple.org/xtincident/view/bugs/20549)
-  _You should be able to assign extensions in user accunt roles as well as user accounts_
-- Fixed
-  issue #[20555](http://www.xtuple.org/xtincident/view/bugs/20555)
-  _new authentication does not work with pgbouncer_
-- Fixed
-  issue #[20563](http://www.xtuple.org/xtincident/view/bugs/20563)
-  _Action - Change Password requires 6 digits_
-- Fixed
-  issue #[20583](http://www.xtuple.org/xtincident/view/bugs/20583)
-  _Authentication not remembered_
-- Fixed
-  issue #[20601](http://www.xtuple.org/xtincident/view/bugs/20601)
-  _There is no tracking of version numbers in extensions_
-- Fixed
-  issue #[20609](http://www.xtuple.org/xtincident/view/bugs/20609)
-  _Incident plus broken_
-- Fixed
-  issue #[20637](http://www.xtuple.org/xtincident/view/bugs/20637)
-  _The attach button should not be available on Customer for Sales Orders and Quotes_
-- Fixed
-  issue #[20638](http://www.xtuple.org/xtincident/view/bugs/20638)
-  _Attach option on relation boxes should not display objects already attached to other objects_
-
-1.3.8 (2013/06/19)
-==================
-
-Features and bugfixes
-----------------
-- Fixed
-  issue #[20605](http://www.xtuple.org/xtincident/view/bugs/20605)
-  _Web client does not use the metric to determine the welcome page URL path_
-
-1.3.7 (2013/06/11)
-==================
-
-Features and bugfixes
-----------------
-- Fixed problem where user names that are email addresses could not log in.
-
-1.3.6 (2013/06/06)
-==================
-
-Features and bugfixes
-----------------
-* Fix critical user login problem
-- Fixed
-  issue #[20505](http://www.xtuple.org/xtincident/view/bugs/20505)
-  _Remove print menus and buttons until Pentaho service available on cloud deployment._
-
-1.3.5 (2013/05/31)
-===============
-
-Critical deployment changes
----------------------------
-* Add redirectPort and maintenancePort to config.js, see sample_config.js
-* To run tests you will need to add the test database to the login_data.js
-  file, per the conventions in sample_login_data.js. Note also the new
-  snake_case filename convention. You will also need to add this database
-  name to your config.js file under datasource.testDatabase.
-* Changed XT.Data's handling of Dates and nulls to work with current version of plv8
-  that doesn't require any special handling. You need to be on this plv8 version:
-
-> commit d75184e00e08e97bc8caba6c9677f8f375a051aa
-
-> Date:   Wed Feb 20 00:10:56 2013 -0800
-
-  To find your current plv8 version:
-
-      cd ~/plv8js
-      git log -1
-
-  To move to that plv8 from your current:
-
-      mv plv8js plv8js-old
-      git clone https://code.google.com/p/plv8js/
-      cd plv8js
-      git checkout d75184e00e08e97bc8caba6c9677f8f375a051aa
-      # Make sure this is the path to your V8 source:
-      make V8_SRCDIR=/home/dev/v8
-      sudo make install
-      # Restart PostgreSQL Server
-      sudo /etc/init.d/postgresql restart
-
-  To test if your plv8 is working correctly, try adding a comment to an Account or Contact.
-  See if you get any errors in your browsers Javascript Console and make sure the comment saves.
-
-Features and bugfixes
-----------------
-
-- Implemented parts of
-  issue #[20264](http://www.xtuple.org/xtincident/view/bugs/20264)
-  REST - Refactor error handling in the database layer
-- Fixed
-  issue #[20448](http://www.xtuple.org/xtincident/view/bugs/20448)
-  _Entering wrong password on mobile client does not return error_
-- Fixed
-  issue #[20441](http://www.xtuple.org/xtincident/view/bugs/20441)
-  _Redirect Port other than 80 does not work_
-- Fixed
-  issue #[20347](http://www.xtuple.org/xtincident/view/bugs/20347)
-  _Default country not working on CRM configuration_
-- Fixed
-  issue #[20319](http://www.xtuple.org/xtincident/view/bugs/20319)
-  _Unable to select first menu after selecting a different menu option_
-- Fixed
-  issue #[20310](http://www.xtuple.org/xtincident/view/bugs/20310)
-  _Next number is a formatted number in sales config_
-- Fixed
-  issue #[20307](http://www.xtuple.org/xtincident/view/bugs/20307)
-  _Can't attach multiple customers to group_
-- Fixed
-  issue #[20297](http://www.xtuple.org/xtincident/view/bugs/20297)
-  _JSON-Patch needs to point to http, not git_
-- Implemented
-  issue #[20295](http://www.xtuple.org/xtincident/view/bugs/20295)
-  _move all ports into config.js_
-- Fixed
-  issue #[20270](http://www.xtuple.org/xtincident/view/bugs/20270)
-  _*Omnibus :Description label is displayed incorrectly_
-- Fixed
-  issue #[20266](http://www.xtuple.org/xtincident/view/bugs/20266)
-  _SQL Injection exploit in XT.Data_
-- Implemented
-  issue #[20254](http://www.xtuple.org/xtincident/view/bugs/20254)
-  _Integrate web-mobile user management into the application database_
-- Fixed
-  issue #[20240](http://www.xtuple.org/xtincident/view/bugs/20240)
-  _Updating ORM uses Username instead of specified -u user_
-- Implemented
-  issue #[20212](http://www.xtuple.org/xtincident/view/bugs/20212)
-  _Build out time and expense portion of "PPM"_
-- Fixed
-  issue #[20208](http://www.xtuple.org/xtincident/view/bugs/20208)
-  _User account assignment box is broken_
-- Fixed
-  issue #[20199](http://www.xtuple.org/xtincident/view/bugs/20199)
-  _Unable to select line item for a quote_
-- Fixed
-  issue #[20180](http://www.xtuple.org/xtincident/view/bugs/20180)
-  _*It is not possible to filter the Customers screen using Advanced Search window_
-- Fixed
-  issue #[20177](http://www.xtuple.org/xtincident/view/bugs/20177)
-  _* It is not possible to assign 'Tax Authority' role to a CRM Account_
-- Fixed
-  issue #[20162](http://www.xtuple.org/xtincident/view/bugs/20162)
-  _*Text box is displayed irrelevantly for the Currency field in the Tax Rate screen_
-- Fixed
-  issue #[20157](http://www.xtuple.org/xtincident/view/bugs/20157)
-  _Incident relations not showing_
-- Fixed
-  issue #[20078](http://www.xtuple.org/xtincident/view/bugs/20078)
-  _Priv Error when trying to add a custom command_
-- Implemented
-  issue #[20052](http://www.xtuple.org/xtincident/view/bugs/20052)
-  _Tax rate ORM, model, and views need to be added_
-- Implemented
-  issue #[20041](http://www.xtuple.org/xtincident/view/bugs/20041)
-  _build extensions dynamically through node_
-- Implemented
-  issue #[20040](http://www.xtuple.org/xtincident/view/bugs/20040)
-  _Add support for Sales Orders_
-- Fixed
-  issue #[20026](http://www.xtuple.org/xtincident/view/bugs/20026)
-  _*Irrelevant behavior is observed on selecting to assign Tax Authority/Sales Rep role to a CRM account_
-- Fixed
-  issue #[20024](http://www.xtuple.org/xtincident/view/bugs/20024)
-  _*Omnibus : Records data  grayed out on editing and refreshing to save the changes made_
-- Fixed
-  issue #[20011](http://www.xtuple.org/xtincident/view/bugs/20011)
-  _*Chrome : Omnibus :Irrelavant dates are displayed on selecting to enter Date starting with special character_
-- Fixed
-  issue #[19976](http://www.xtuple.org/xtincident/view/bugs/19976)
-  _Quote for prospect requires ship-to_
-- Fixed
-  issue #[19970](http://www.xtuple.org/xtincident/view/bugs/19970)
-  _Cannot open an Opportunity from a To Do_
-- Fixed
-  issue #[19932](http://www.xtuple.org/xtincident/view/bugs/19932)
-  _Characteristics not completely working on quote_
-- Fixed
-  issue #[19889](http://www.xtuple.org/xtincident/view/bugs/19889)
-  _*Omnibus: Selecting to enter a number with more than 10 digits in 'Order' field shows irrelevant behavior_
-- Fixed
-  issue #[19888](http://www.xtuple.org/xtincident/view/bugs/19888)
-  _Unable to enter a number with more than 12 digits in the 'Expenses' section under the 'Project Tasks' widget of a Project screen_
-- Fixed
-  issue #[19871](http://www.xtuple.org/xtincident/view/bugs/19871)
-  _*Tab out from an Items 'Extended Description' field displays an irrelevant dialog_
-- Fixed
-  issue #[19844](http://www.xtuple.org/xtincident/view/bugs/19844)
-  _Clicking in Blank Space causes error_
-- Fixed
-  issue #[19833](http://www.xtuple.org/xtincident/view/bugs/19833)
-  _New privileges installed by packages do not appear_
-- Fixed
-  issue #[19830](http://www.xtuple.org/xtincident/view/bugs/19830)
-  _The advanced search box is wider than the panel_
-- Implemented
-  issue #[19795](http://www.xtuple.org/xtincident/view/bugs/19795)
-  _Numbers on number widgets should be right justified_
-- Fixed
-  issue #[19677](http://www.xtuple.org/xtincident/view/bugs/19677)
-  _*It is possible to enter 'End Date'  prior to 'Start Date' for a Tax Registration Number under 'Tax Registration Numbers' widget_
-- Fixed
-  issue #[19676](http://www.xtuple.org/xtincident/view/bugs/19676)
-  _* Omnibus: Discarding the changes made in a Project Task shows unexpected behaviour_
-- Fixed
-  issue #[19658](http://www.xtuple.org/xtincident/view/bugs/19658)
-  _* Omnibus :'To Do' associated to the 'Customer' is displayed as locked on selecting to open_
-- Fixed
-  issue #[19632](http://www.xtuple.org/xtincident/view/bugs/19632)
-  _*Unable to attach a new file to a record_
-- Fixed
-  issue #[19616](http://www.xtuple.org/xtincident/view/bugs/19616)
-  _*Back button is not working on selecting to discard the changes made in a CRM Account's Role_
-- Fixed
-  issue #[19599](http://www.xtuple.org/xtincident/view/bugs/19599)
-  _Maxhammer Mobile Users created with improper SUPERUSER roles and overview of proper db creation process._
-- Fixed
-  issue #[19542](http://www.xtuple.org/xtincident/view/bugs/19542)
-  _Shipping charges prevent customer edit_
-- Fixed
-  issue #[19471](http://www.xtuple.org/xtincident/view/bugs/19471)
-  _Unable to create custom commands in dogfood_
-- Fixed
-  issue #[19045](http://www.xtuple.org/xtincident/view/bugs/19045)
-  _ Omnibus : Database error is displayed on selecting to duplicate existing records_
-- Fixed
-  issue #[19033](http://www.xtuple.org/xtincident/view/bugs/19033)
-  _Irrelavant behaviour is observed in Project task screen_
-- Fixed
-  issue #[18958](http://www.xtuple.org/xtincident/view/bugs/18958)
-  _Errors preventing creation of new item_
-- Implemented
-  issue #[18757](http://www.xtuple.org/xtincident/view/bugs/18757)
-  _REST - Modify the XT.Data commit code to enforce the new requiredAttributes driven by db NOT NULL and ORM override_
-
-
-1.3.4 (2013/05/06)
-===============
-
-Features and bugfixes
------------------
-- Fixed
-  issue #[20169](http://www.xtuple.org/xtincident/view/bugs/20169)
-  _etag versions not working with usr and org string pkeys_
-- Implemented
-  issue #[18716](http://www.xtuple.org/xtincident/view/bugs/18716)
-  _REST - Create helper functions needed to generate API Directory list and Discovery Documents_
-- Implemented
-  issue #[19304](http://www.xtuple.org/xtincident/view/bugs/19304)
-  _REST - Add route generator for resource end points_
-- Fixed
-  issue #[19870](http://www.xtuple.org/xtincident/view/bugs/19870)
-  _Unable to attach a contact related to a CRM Account under Documents widget of an accounts screen_
-- Fixed
-  issue #[19905](http://www.xtuple.org/xtincident/view/bugs/19905)
-  _Documents attached under the document widget of a record are not displayed on selecting to reopen the record_
-- Fixed
-  issue #[20214](http://www.xtuple.org/xtincident/view/bugs/20214)
-  _incorrect login brings up error screen_
-- Fixed
-  issue #[20235](http://www.xtuple.org/xtincident/view/bugs/20235)
-  _Selecting to enter the address for a contact displays an error message in the console_
-- Fixed
-  issue #[20205](http://www.xtuple.org/xtincident/view/bugs/20205)
-  _Select Organization for a User - "ID is required" Error_
-- Fixed
-  issue #[20184](http://www.xtuple.org/xtincident/view/bugs/20184)
-  _List lazy-loading problem_
-- Fixed
-  issue #[19953](http://www.xtuple.org/xtincident/view/bugs/19953)
-  _Cannot use a prospect to save a quote_
-- Fixed
-  issue #[19973](http://www.xtuple.org/xtincident/view/bugs/19973)
-  _percent widget is broken_
-- Fixed
-  issue #[20026](http://www.xtuple.org/xtincident/view/bugs/20026)
-  _*Irrelevant behavior is observed on selecting to assign Tax Authority/Sales Rep role to a CRM account_
-- Implemented
-  issue #[20154](http://www.xtuple.org/xtincident/view/bugs/20154)
-  _Add support for natural keys on orms_
-- Fixed
-  issue #[20066](http://www.xtuple.org/xtincident/view/bugs/20066)
-  _*Irrelevant dialog is displayed on selecting to save a Tax Class_
-- Implemented
-  issue #[20044](http://www.xtuple.org/xtincident/view/bugs/20044)
-  _Add support JSON Patch_
-- Implemented
-  issue #[20052](http://www.xtuple.org/xtincident/view/bugs/20052)
-  _Tax rate ORM, model, and views need to be added_
-- Implemented
-  issue #[20054](http://www.xtuple.org/xtincident/view/bugs/20054)
-  _installer should work atomically on one org at a time_
-
-
-1.3.3 (2013/04/18)
-===============
-
-Critical deployment changes
----------------------------
-* You need to add
-  <code>"lib/ext/smtpTransport"</code>
-  as a requirement in your config.js. See
-  [sample_config.js](https://github.com/xtuple/xtuple/blob/master/node-datasource/sample_config.js) for details.
-* We removed node-datasource/lib/private/salt.txt from version control. You
-  will have to put this file back in yourself. You can fill it with any long string you want.
-* You need to implement npm changes, config.js changes, and the deletion of a global table as documented
-  [here](https://github.com/xtuple/xtuple/pull/224).
-* We are now running on [our own fork of plv8](https://github.com/xtuple/plv8).
-
-
-Features and bugfixes
------------------
-- Fixed
-  issue #[19246](http://www.xtuple.org/xtincident/view/bugs/19246)
-  _Help file iframe issue on Firefox_
-- Fixed
-  issue #[19593](http://www.xtuple.org/xtincident/view/bugs/19593)
-  _Record Lock - No Error when attaching a Locked Contact to Account_
-- Fixed
-  issue #[19450](http://www.xtuple.org/xtincident/view/bugs/19450)
-  _Updating setup items does not update their collections and pickers_
-- Fixed
-  issue #[19469](http://www.xtuple.org/xtincident/view/bugs/19469)
-  _customer edit ship-to bug_
-- Implemented
-  issue #[19442](http://www.xtuple.org/xtincident/view/bugs/19442)
-  _Add schema to data routes for Pentaho reports_
-- Implemented
-  issue #[19296](http://www.xtuple.org/xtincident/view/bugs/19296)
-  _OAuth 2.0 - After switching to ONLY Express, remove dead code in node-xt and node-datasource_
-- Fixed
-  issue #[19813](http://www.xtuple.org/xtincident/view/bugs/19813)
-  _Create list and view to maintain customer groups_
-- Implemented
-  issue #[19812](http://www.xtuple.org/xtincident/view/bugs/19812)
-  _Create list and view to maintain customer types_
-- Implemented
-  issue #[19818](http://www.xtuple.org/xtincident/view/bugs/19818)
-  _List cost should be added to item workspace_
-- Implemented
-  issue #[19811](http://www.xtuple.org/xtincident/view/bugs/19811)
-  _Create list and view to maintain sales reps_
-- Implemented
-  issue #[19847](http://www.xtuple.org/xtincident/view/bugs/19847)
-  _Additional mobile db Org Attributes Fields/tables to support automation and data collection required for campaigns etc._
-- Implemented
-  issue #[19815](http://www.xtuple.org/xtincident/view/bugs/19815)
-  _Create list and workspace for freight class_
-- Implemented
-  issue #[19821](http://www.xtuple.org/xtincident/view/bugs/19821)
-  _Create list and workspace for ship zone_
-- Fixed
-  issue #[19840](http://www.xtuple.org/xtincident/view/bugs/19840)
-  _Quotes panel MISSING on Opportunity, Prospect and Customer_
-- Fixed
-  issue #[20007](http://www.xtuple.org/xtincident/view/bugs/20007)
-  _Parent CRM account not created when prospect created_
-- Implemented
-  issue #[19814](http://www.xtuple.org/xtincident/view/bugs/19814)
-  _Create list and views for tax maintenance_
-- Implemented
-  issue #[19822](http://www.xtuple.org/xtincident/view/bugs/19822)
-  _Create list and workspace for terms_
-- Fixed
-  issue #[20022](http://www.xtuple.org/xtincident/view/bugs/20022)
-  _Project numbers are disabled in incidents_
-- Fixed
-  issue #[19703](http://www.xtuple.org/xtincident/view/bugs/19703)
-  _speed up update_
-- Implemented
-  issue #[19972](http://www.xtuple.org/xtincident/view/bugs/19972)
-  _Proposal for BI for Sales based on Pentaho Community_
-- Fixed
-  issue #[19806](http://www.xtuple.org/xtincident/view/bugs/19806)
-  _Quote summary needs cosmetic work_
-- Fixed
-  issue #[19930](http://www.xtuple.org/xtincident/view/bugs/19930)
-  _Search on Address in Quote does not work_
-- Implemented
-  issue #[19989](http://www.xtuple.org/xtincident/view/bugs/19989)
-  _Add a section to display version number_
-- Implemented
-  issue #[19823](http://www.xtuple.org/xtincident/view/bugs/19823)
-  _Create list and workspace for sale type_
-- Fixed
-  issue #[20039](http://www.xtuple.org/xtincident/view/bugs/20039)
-  _State Dropdown does not appear correctly when editing Ship-To_
-- Fixed
-  issue #[19804](http://www.xtuple.org/xtincident/view/bugs/19804)
-  _Cost on quote line items should show the local currency_
-- Implemented
-  issue #[20053](http://www.xtuple.org/xtincident/view/bugs/20053)
-  _Incident filter by foundIn and fixedIn_
-- Fixed
-  issue #[20067](http://www.xtuple.org/xtincident/view/bugs/20067)
-  _Customer Groups does not give error when saving with Blank Name_
-- Fixed
-  issue #[20073](http://www.xtuple.org/xtincident/view/bugs/20073)
-  _Numerous problems with customer shipto_
index f15e09a..c3ae3c8 100644 (file)
@@ -125,6 +125,14 @@ white:true*/
         params.length = "3";
         return XT.Error.clone('xt1006', { params: params });
       }
+
+      if (attributes.currencyNumber &&
+          attributes.currencyNumber.length !== 3) {
+        params.attr = "_currencyNumber".loc();
+        params.length = "3";
+        return XT.Error.clone('xt1006', { params: params });
+      }
+
       return XM.Document.prototype.validate.apply(this, arguments);
     }
 
index 5ed3085..4597280 100644 (file)
@@ -93,7 +93,15 @@ white:true*/
 
     recordType: 'XM.SiteListItem',
 
-    editableModel: 'XM.Site'
+    editableModel: 'XM.Site',
+
+    couldCreate: function () {
+      // Look to see if there are sites in the sites cache. If so, restrict new for Postbooks.
+      if (!XM.sites.length) {
+        return XM.Info.prototype.couldCreate.apply(this, arguments);
+      }
+      return false;
+    }
 
   });
 
index aa5b973..b32de15 100644 (file)
@@ -690,10 +690,13 @@ trailing:true, white:true, strict: false*/
             {kind: "XV.ListAttr", attr: "billingContact.phone", },
             {kind: "XV.ListAttr", attr: "billingContact.primaryEmail"}
           ]},
-          {kind: "XV.ListColumn", fit: true, components: [
+          {kind: "XV.ListColumn", classes: "descr", components: [
             {kind: "XV.ListAttr", attr: "billingContact.name",
               placeholder: "_noContact".loc()},
             {kind: "XV.ListAttr", attr: "billingContact.address"}
+          ]},
+          {kind: "XV.ListColumn", fit: true, components: [
+            {kind: "XV.ListAttr", attr: "customerType.code"}
           ]}
         ]}
       ]}
@@ -2531,7 +2534,7 @@ trailing:true, white:true, strict: false*/
       ]}
     ]
   });
-  
+
   XV.registerModelList("XM.UserAccountRelation", "XV.UserAccountList");
 
   // ..........................................................
index a0e9ba6..f74658d 100644 (file)
@@ -641,12 +641,12 @@ strict: false*/
           {kind: "onyx.GroupboxHeader", content: "_overview".loc()},
           {kind: "XV.ScrollableGroupbox", name: "mainGroup",
             classes: "in-panel", components: [
-            {kind: "XV.InputWidget", attr: "abbreviation"},
+            {kind: "XV.InputWidget", attr: "abbreviation", maxlength: 2},
             {kind: "XV.InputWidget", attr: "name"},
             {kind: "XV.InputWidget", attr: "currencyName"},
             {kind: "XV.InputWidget", attr: "currencySymbol"},
-            {kind: "XV.InputWidget", attr: "currencyAbbreviation"},
-            {kind: "XV.InputWidget", attr: "currencyNumber"}
+            {kind: "XV.InputWidget", attr: "currencyAbbreviation", maxlength: 3},
+            {kind: "XV.InputWidget", attr: "currencyNumber", maxlength: 3}
           ]}
         ]}
       ]}
@@ -2785,19 +2785,17 @@ strict: false*/
           {kind: "onyx.GroupboxHeader", content: "_overview".loc()},
           {kind: "XV.ScrollableGroupbox", name: "mainGroup", fit: true,
             classes: "in-panel", components: [
-            {kind: "XV.InputWidget", attr: "code"},
-            {kind: "XV.CheckboxWidget", attr: "isActive"},
-            {kind: "XV.SiteTypePicker", attr: "siteType"},
-            {kind: "XV.InputWidget", attr: "description"},
-            {kind: "XV.ContactWidget", attr: "contact"},
-            {kind: "XV.AddressWidget", attr: "address"},
-            {kind: "XV.TaxZonePicker", attr: "taxZone"},
-            {kind: "XV.InputWidget", attr: "incoterms"},
-            {kind: "onyx.GroupboxHeader", content: "_notes".loc()},
-            {kind: "XV.TextArea", attr: "notes", fit: true}
+            {name: "mainSubgroup", components: [ // not a scroller, so we can addBefore
+              {kind: "XV.InputWidget", attr: "code"},
+              {kind: "XV.CheckboxWidget", attr: "isActive"},
+              {kind: "XV.SiteTypePicker", attr: "siteType"},
+              {kind: "XV.InputWidget", attr: "description"},
+              {kind: "XV.ContactWidget", attr: "contact", name: "contactWidget"},
+              {kind: "XV.AddressWidget", attr: "address"}
+            ]}
           ]}
         ]},
-        {kind: "XV.SiteCommentBox", attr: "comments"}
+        {kind: "XV.SiteCommentBox", attr: "comments", name: "commentsPanel"}
       ]}
     ]
   });
@@ -3345,5 +3343,4 @@ strict: false*/
   XV.registerModelWorkspace("XM.UserAccountRoleRelation", "XV.UserAccountRoleWorkspace");
   XV.registerModelWorkspace("XM.UserAccountRoleListItem", "XV.UserAccountRoleWorkspace");
 
-
 }());
index ae86963..6c31ae2 100644 (file)
           "column": "cust_active"
         }
       },
+      {
+        "name": "customerType",
+        "toOne": {
+          "isNested": true,
+          "type": "CustomerType",
+          "column": "cust_custtype_id"
+        }
+      },
       {
         "name": "billingContact",
         "toOne": {
index d567c11..85a20d6 100644 (file)
@@ -38,7 +38,8 @@
         "name": "name",
         "attr": {
           "type": "String",
-          "column": "dept_name"
+          "column": "dept_name",
+          "required": true
         }
       }
     ],
@@ -83,7 +84,8 @@
         "name": "name",
         "attr": {
           "type": "String",
-          "column": "shift_name"
+          "column": "shift_name",
+          "required": true
         }
       }
     ],
index 8b1dca0..3ffb2f7 100644 (file)
@@ -31,7 +31,8 @@
         "attr": {
           "type": "String",
           "column": "warehous_code",
-          "isNaturalKey":true
+          "isNaturalKey":true,
+          "required": true
         }
       },
       {
@@ -39,7 +40,8 @@
         "toOne": {
           "isNested": true,
           "type": "SiteType",
-          "column": "warehous_sitetype_id"
+          "column": "warehous_sitetype_id",
+          "required": true
         }
       },
       {
           "column": "warehous_fob"
         }
       },
-      {
-        "name": "notes",
-        "attr": {
-          "type": "String",
-          "column": "warehous_shipcomments"
-        }
-      },
       {
         "name": "comments",
         "toMany": {
index fa626f8..6aa15db 100644 (file)
@@ -18,7 +18,7 @@ from (
   where aropen_cust_id = $1
   and aropen_open
   --and aropen_posted = false
-  group by aropen_id
+  group by aropen_id, aropen_cust_id, aropen_curr_id, aropen_amount
 ) unalloc;
 
 $$ language sql;
index c972418..d438be2 100644 (file)
@@ -48,7 +48,6 @@ insert into itemsite (
   itemsite_location_comments,
   itemsite_notes,
   itemsite_perishable,
-  itemsite_nnqoh,
   itemsite_autoabcclass,
   itemsite_ordergroup,
   itemsite_disallowblankwip,
@@ -109,7 +108,6 @@ insert into itemsite (
   new.itemsite_location_comments,
   new.itemsite_notes,
   coalesce(new.itemsite_perishable, false),
-  0,
   coalesce(new.itemsite_autoabcclass, false),
   coalesce(new.itemsite_ordergroup, 1),
   coalesce(new.itemsite_disallowblankwip, false),
index 70fc13a..d8078ce 100644 (file)
@@ -7,10 +7,7 @@ white:true*/
   "use strict";
 
   XT.extensions.billing = {
-    name: "billing",
-    setVersion: function () {
-      XT.setVersion("", XT.extensions.billing.name);
-    }
+    name: "billing"
   };
 
 }());
index ecd07aa..938c9d3 100644 (file)
@@ -1,4 +1,4 @@
-select xt.add_report_definition('XM.Invoice', 0, $${
+select xt.add_report_definition('XM.Invoice', 0, $${
   "settings": {
     "detailAttribute": "lineItems",
     "defaultFontSize": 12,
@@ -151,12 +151,31 @@ select xt.add_report_definition('XM.Invoice', 0, $${
     },
     {"element": "bandLine", "size": 2},
     {
+      "element": "band",
       "definition": [
-        {"attr": "subtotal", "label": true},
-        {"attr": "taxTotal", "label": true},
-        {"attr": "total", "label": true}
+        {"text": "_subtotal", "label": true, "width": 70, "align": "left"},
+        {"attr": "subtotal", "width": 100, "align": "right"}
       ],
-      "options": {"width": 525, "align": "right"}
+      "options": {"border": 0, "x": 360}
+    },
+    {
+      "element": "band",
+      "definition": [
+        {"text": "_taxTotal", "label": true, "width": 70, "align": "left"},
+        {"attr": "taxTotal", "width": 100, "align": "right"}
+      ],
+      "options": {"border": 0, "x": 360}
+    },
+    {
+      "element": "band",
+      "definition": [
+        {"text": "_total", "label": true, "width": 70, "align": "left"},
+        {"attr": "total", "width": 100, "align": "right"}
+      ],
+      "options": {"border": 0, "x": 360}
+    },
+    {
+      "definition": []
     }
   ],
   "pageFooterElements": [
index 2691507..b1489bf 100644 (file)
@@ -6,10 +6,6 @@ white:true*/
 (function () {
   "use strict";
 
-  XT.extensions.crm = {
-    setVersion: function () {
-      XT.setVersion("", "crm");
-    }
-  };
+  XT.extensions.crm = {};
 
 }());
index 50c6ad1..17bb596 100644 (file)
@@ -6,10 +6,6 @@ white:true*/
 (function () {
   "use strict";
 
-  XT.extensions.oauth2 = {
-    setVersion: function () {
-      XT.setVersion("4.4.0", "oauth2");
-    }
-  };
+  XT.extensions.oauth2 = {};
 
 }());
index f34b602..fc5d4e3 100644 (file)
@@ -17,9 +17,9 @@ strict:true, trailing:true, white:true */
     "_issued": "Issued",
     "_fullListUrl": "Full List URL",
     "_generatingPrivateKey": "A new keypair will be generated for this OAUTH2 client. " +
-      "The public key will be saved in the database with this client. The private key " +
-      "is available as a one-time download. The password for the key store file will be " +
-      "\"notasecret\". Click \"ok\" to downloading the private key.",
+      "The public key will be available in the future with this client. The private key " +
+      "is only available now as a one-time download. Note that this process can take up " +
+      "to a minute. Please wait until the key is downloaded.",
     "_logoURL": "Logo URL",
     "_maintainOauth2clients": "Maintain OAUTH2 Clients",
     "_oauth2": "OAUTH2",
index 7124aff..a967d4c 100644 (file)
@@ -6,10 +6,6 @@ white:true*/
 (function () {
   "use strict";
 
-  XT.extensions.project = {
-    setVersion: function () {
-      XT.setVersion("", "project");
-    }
-  };
+  XT.extensions.project = {};
 
 }());
index d7ec1e8..d88578a 100644 (file)
@@ -6,10 +6,6 @@ white:true*/
 (function () {
   "use strict";
 
-  XT.extensions.purchasing = {
-    setVersion: function () {
-      XT.setVersion("", "purchasing");
-    }
-  };
+  XT.extensions.purchasing = {};
 
 }());
index 40bbfd6..0ea1d73 100644 (file)
@@ -6,10 +6,6 @@ white:true*/
 (function () {
   "use strict";
 
-  XT.extensions.sales = {
-    setVersion: function () {
-      XT.setVersion("", "sales");
-    }
-  };
+  XT.extensions.sales = {};
 
 }());
index a4a67c4..dcda6af 100644 (file)
@@ -7,6 +7,7 @@
   "databaseScripts": [
     "../lib/orm/source/create_xt_schema.sql",
     "../lib/orm/source/xt/functions/add_column.sql",
+    "../lib/orm/source/xt/functions/add_comment_type.sql",
     "../lib/orm/source/xt/functions/add_constraint.sql",
     "../lib/orm/source/xt/functions/add_index.sql",
     "../lib/orm/source/xt/functions/add_primary_key.sql",
     "public/functions/haspriv.sql",
     "public/functions/hasprivonobject.sql",
     "public/functions/implodewo.sql",
+    "public/functions/importbankreccleared.sql",
     "public/functions/incdt.sql",
     "public/functions/indentedbom.sql",
     "public/functions/indentedwhereused.sql",
     "public/functions/purgepostedcounttags.sql",
     "public/functions/purgeshipments.sql",
     "public/functions/qtyallocated.sql",
+    "public/functions/qtyatlocation.sql",
     "public/functions/qtyatshipping.sql",
     "public/functions/qtyavailable.sql",
     "public/functions/qtyinshipment.sql",
     "public/functions/qtylocation.sql",
+    "public/functions/qtynetable.sql",
     "public/functions/qtyordered.sql",
     "public/functions/qtypr.sql",
     "public/functions/qtyreserved.sql",
     "public/trigger_functions/wo.sql",
     "public/trigger_functions/womatl.sql",
 
+    "public/tables/bankrecimport.sql",
     "public/tables/bankrecitem.sql",
     "public/tables/cashrcpt.sql",
     "public/tables/ccpay.sql",
     "public/tables/ccbank.sql",
     "public/tables/checkhead.sql",
+    "public/tables/itemsite.sql",
+    "public/tables/location.sql",
     "public/tables/metric.sql",
     "public/tables/payco.sql",
     "public/tables/priv.sql",
     "public/tables/tax.sql",
     "public/tables/taxpay.sql",
 
-    "public/tables/location.sql",
     "public/views/address.sql",
     "public/views/apmemo.sql",
     "public/views/armemo.sql",
     "public/tables/report/items.xml",
 
     "public/patches/fixacl.sql",
-    "public/patches/populate_ccpay_card_type.sql"
+    "public/patches/populate_ccpay_card_type.sql",
+
+    "public/tables/setVersion.sql"
   ]
 }
index 78a7ba9..a076ade 100644 (file)
@@ -41002,6 +41002,9 @@ INSERT INTO locale (locale_id, locale_code, locale_descrip, locale_lang_file, lo
 INSERT INTO locale (locale_id, locale_code, locale_descrip, locale_lang_file, locale_dateformat, locale_currformat, locale_qtyformat, locale_comments, locale_qtyperformat, locale_salespriceformat, locale_extpriceformat, locale_timeformat, locale_timestampformat, local_costformat, locale_costformat, locale_purchpriceformat, locale_uomratioformat, locale_intervalformat, locale_lang_id, locale_country_id, locale_error_color, locale_warning_color, locale_emphasis_color, locale_altemphasis_color, locale_expired_color, locale_future_color, locale_curr_scale, locale_salesprice_scale, locale_purchprice_scale, locale_extprice_scale, locale_cost_scale, locale_qty_scale, locale_qtyper_scale, locale_uomratio_scale, locale_percent_scale, locale_weight_scale) VALUES (28, 'Finance', 'Finance', '', 'MM/DD/YY', '999,999,990', '.-,', '', '999,999,990.0000', '999,999,990.0000', '999,999,990.00', 'HH12:MI AM', 'MM/DD/YY HH12:MI AM', NULL, '999,999,990.0000', '999,999,990.0000', '', 'HH2424:MI ', 352, 230, '', '', '', '', '', '', 0, 4, 4, 2, 4, 2, 4, 0, 2, 2);
 INSERT INTO locale (locale_id, locale_code, locale_descrip, locale_lang_file, locale_dateformat, locale_currformat, locale_qtyformat, locale_comments, locale_qtyperformat, locale_salespriceformat, locale_extpriceformat, locale_timeformat, locale_timestampformat, local_costformat, locale_costformat, locale_purchpriceformat, locale_uomratioformat, locale_intervalformat, locale_lang_id, locale_country_id, locale_error_color, locale_warning_color, locale_emphasis_color, locale_altemphasis_color, locale_expired_color, locale_future_color, locale_curr_scale, locale_salesprice_scale, locale_purchprice_scale, locale_extprice_scale, locale_cost_scale, locale_qty_scale, locale_qtyper_scale, locale_uomratio_scale, locale_percent_scale, locale_weight_scale) VALUES (4, 'Spanish', 'Locale for Mexican Spanish', 'OpenMFG.mx.sp', 'DD/MM/YY', '999999990.00', '.-,', '', '999999990.0000', '999999990.0000', '999999990.00', 'HH:MI', 'DD/MM/YY HH:MI', NULL, '999999990.0000', '', '', 'HH24:MI', 354, 140, '', '', '', '', '', '', 2, 4, 0, 2, 4, 2, 4, 0, 2, 2);
 INSERT INTO locale (locale_id, locale_code, locale_descrip, locale_lang_file, locale_dateformat, locale_currformat, locale_qtyformat, locale_comments, locale_qtyperformat, locale_salespriceformat, locale_extpriceformat, locale_timeformat, locale_timestampformat, local_costformat, locale_costformat, locale_purchpriceformat, locale_uomratioformat, locale_intervalformat, locale_lang_id, locale_country_id, locale_error_color, locale_warning_color, locale_emphasis_color, locale_altemphasis_color, locale_expired_color, locale_future_color, locale_curr_scale, locale_salesprice_scale, locale_purchprice_scale, locale_extprice_scale, locale_cost_scale, locale_qty_scale, locale_qtyper_scale, locale_uomratio_scale, locale_percent_scale, locale_weight_scale) VALUES (29, 'UK', 'United Kingdom', '', 'DD/MM/YYYY', '999,999,990.00', '.-,', '', '999,999,990.0000', '999,999,990.0000', '999,999,990.00', 'HH:MI', 'DD/MM/YYYY HH:MI', NULL, '999,999,990.0000', '999,999,990.0000', '999,999,990.00000', 'HH24:MI', 352, 229, '', '', '', '', '', '', 2, 4, 4, 2, 4, 2, 4, 5, 2, 2);
+INSERT INTO locale (locale_code, locale_descrip, locale_lang_file, locale_dateformat, locale_currformat, locale_qtyformat, locale_comments, locale_qtyperformat, locale_salespriceformat, locale_extpriceformat, locale_timeformat, locale_timestampformat, local_costformat, locale_costformat, locale_purchpriceformat, locale_uomratioformat, locale_intervalformat, locale_lang_id, locale_country_id, locale_error_color, locale_warning_color, locale_emphasis_color, locale_altemphasis_color, locale_expired_color, locale_future_color, locale_curr_scale, locale_salesprice_scale, locale_purchprice_scale, locale_extprice_scale, locale_cost_scale, locale_qty_scale, locale_qtyper_scale, locale_uomratio_scale, locale_percent_scale, locale_weight_scale) VALUES ('French', 'French', '', 'DD/MM/YY', '999,999,990.00', ',- ', '', '999,999,990.0000', '999,999,990.0000', '999,999,990.00', 'HH:MI', 'DD/MM/YY HH:MI', NULL, '999,999,990.0000', '999,999,990.0000', '999,999,990.000', 'HH24:MI', 362, 74, '', '', '', '', '', '', 2, 4, 4, 2, 4, 2, 4, 3, 2, 2);
+INSERT INTO locale (locale_code, locale_descrip, locale_lang_file, locale_dateformat, locale_currformat, locale_qtyformat, locale_comments, locale_qtyperformat, locale_salespriceformat, locale_extpriceformat, locale_timeformat, locale_timestampformat, local_costformat, locale_costformat, locale_purchpriceformat, locale_uomratioformat, locale_intervalformat, locale_lang_id, locale_country_id, locale_error_color, locale_warning_color, locale_emphasis_color, locale_altemphasis_color, locale_expired_color, locale_future_color, locale_curr_scale, locale_salesprice_scale, locale_purchprice_scale, locale_extprice_scale, locale_cost_scale, locale_qty_scale, locale_qtyper_scale, locale_uomratio_scale, locale_percent_scale, locale_weight_scale) VALUES ('Chinese', 'Simplified Chinese', '', 'DD/MM/YY', '999,999,990.00', ',- ', '', '999,999,990.0000', '999,999,990.0000', '999,999,990.00', 'HH:MI', 'DD/MM/YY HH:MI', NULL, '999,999,990.0000', '999,999,990.0000', '999,999,990.000', 'HH24:MI', 498, 45, '', '', '', '', '', '', 2, 4, 4, 2, 4, 2, 4, 3, 2, 2);
+--INSERT INTO locale (locale_code, locale_descrip, locale_lang_file, locale_dateformat, locale_currformat, locale_qtyformat, locale_comments, locale_qtyperformat, locale_salespriceformat, locale_extpriceformat, locale_timeformat, locale_timestampformat, local_costformat, locale_costformat, locale_purchpriceformat, locale_uomratioformat, locale_intervalformat, locale_lang_id, locale_country_id, locale_error_color, locale_warning_color, locale_emphasis_color, locale_altemphasis_color, locale_expired_color, locale_future_color, locale_curr_scale, locale_salesprice_scale, locale_purchprice_scale, locale_extprice_scale, locale_cost_scale, locale_qty_scale, locale_qtyper_scale, locale_uomratio_scale, locale_percent_scale, locale_weight_scale) VALUES ('Telugu', 'Telugu', '', 'DD/MM/YY', '999,999,990.00', ',- ', '', '999,999,990.0000', '999,999,990.0000', '999,999,990.00', 'HH:MI', 'DD/MM/YY HH:MI', NULL, '999,999,990.0000', '999,999,990.0000', '999,999,990.000', 'HH24:MI', 472, 100, '', '', '', '', '', '', 2, 4, 4, 2, 4, 2, 4, 3, 2, 2);
 
 
 ALTER TABLE locale ENABLE TRIGGER ALL;
index e75b6b6..d701d61 100644 (file)
@@ -164,7 +164,10 @@ BEGIN
       -1,
       NULL,
       _fc.fincharg_markoninvoice,
-      'Finance Charge Assessment',
+--    - enhance data shown in the item description for the invoice line to indicate which invoice is affected
+--    - Feature Request 23344       
+--      'Finance Charge Assessment',
+      'Finance Charge Assessment - Invoice Number ' || _ar.aropen_docnumber || ' - Past Due Balance ' || (_ar.aropen_amount - _ar.aropen_paid) || ' Due Date - ' || _ar.aropen_duedate,
       1.0,
       1.0,
       pAssessAmount,
index 05f1729..19b0028 100644 (file)
@@ -4,16 +4,15 @@ CREATE OR REPLACE FUNCTION avgCost(pItemsiteid INTEGER) RETURNS NUMERIC AS $$
 DECLARE
   _value NUMERIC;
   _qoh NUMERIC;
-  _qohnn NUMERIC;
 BEGIN
-  SELECT itemsite_value, itemsite_qtyonhand, itemsite_nnqoh
-    INTO _value, _qoh, _qohnn
+  SELECT itemsite_value, itemsite_qtyonhand
+    INTO _value, _qoh
     FROM itemsite
    WHERE(itemsite_id=pItemsiteid);
-  IF (_qoh = 0.0 AND _qohnn = 0.0) THEN
+  IF (_qoh = 0.0) THEN
     RETURN 0.0;
   END IF;
-  RETURN _value / (_qoh + _qohnn);
+  RETURN _value / _qoh;
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
 
index 3ae61d0..87d9ddf 100644 (file)
@@ -1,12 +1,10 @@
-CREATE OR REPLACE FUNCTION balanceItemsite(INTEGER) RETURNS INTEGER AS $$
+CREATE OR REPLACE FUNCTION balanceItemsite(pItemsiteid INTEGER) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemsiteid ALIAS FOR $1;
   _itemlocseries INTEGER;
   _balanced NUMERIC;
   _qoh NUMERIC;
-  _nnQoh NUMERIC;
 
 BEGIN
 
@@ -23,13 +21,12 @@ BEGIN
     RETURN -1;
   END IF;
 
---  Calculate the Netable portion
+--  Calculate the qoh
   SELECT COALESCE(SUM(itemloc_qty), 0) INTO _balanced
-  FROM itemloc LEFT OUTER JOIN location ON (itemloc_location_id=location_id)
-  WHERE ( ( (location_id IS NULL) OR (location_netable) )
-   AND (itemloc_itemsite_id=pItemsiteid) );
+  FROM itemloc
+  WHERE (itemloc_itemsite_id=pItemsiteid);
 
---  Post an AD Transaction for the Netable portion
+--  Post an AD Transaction
   SELECT invAdjustment( itemsite_id, (_balanced - itemsite_qtyonhand),
                         'Balance', 'Inventory Balance' ) INTO _itemlocseries
   FROM itemsite
@@ -42,18 +39,7 @@ BEGIN
   DELETE FROM itemlocdist
   WHERE (itemlocdist_series=_itemlocseries);
 
---  Calculate and write the Non-Netable portion directly
-  SELECT COALESCE(SUM(itemloc_qty), 0) INTO _nnQoh
-  FROM itemloc, location
-  WHERE ( (itemloc_location_id=location_id)
-   AND (NOT location_netable)
-   AND (itemloc_itemsite_id=pItemsiteid) );
-
-  UPDATE itemsite
-  SET itemsite_nnqoh = _nnQoh
-  WHERE (itemsite_id=pItemsiteid);
-
   RETURN 1;
 
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index bf15b9b..c9d7759 100644 (file)
@@ -4,6 +4,8 @@ CREATE OR REPLACE FUNCTION convertQuote(INTEGER) RETURNS INTEGER AS $$
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
   pQuheadid ALIAS FOR $1;
+  _qunumber TEXT;
+  _ponumber TEXT;
   _soheadid INTEGER;
   _soitemid INTEGER;
   _orderid INTEGER;
@@ -62,13 +64,20 @@ BEGIN
     RETURN -5;
   END IF;
 
-  IF ( (_usespos) AND (NOT _blanketpos) ) THEN
-    PERFORM cohead_id
-    FROM quhead JOIN cohead ON ( (cohead_cust_id=quhead_cust_id) AND
-                                 (UPPER(cohead_custponumber)=UPPER(quhead_custponumber)) )
+  IF (_usespos) THEN
+    SELECT quhead_number, COALESCE(quhead_custponumber, ''), cohead_id INTO _qunumber, _ponumber, _soheadid
+    FROM quhead LEFT OUTER JOIN cohead ON ( (cohead_cust_id=quhead_cust_id) AND
+                                            (UPPER(cohead_custponumber)=UPPER(quhead_custponumber)) )
     WHERE (quhead_id=pQuheadid);
-    IF (FOUND) THEN
-      RAISE EXCEPTION 'Duplicate Customer PO';
+    IF (_ponumber = '') THEN
+      RAISE EXCEPTION 'Customer PO required for Quote % [xtuple: convertQuote, -7, %]',
+                      _qunumber, _qunumber;
+    END IF;
+  
+    IF ( (NOT _blanketpos) AND (_soheadid IS NOT NULL) ) THEN
+      RAISE EXCEPTION 'Duplicate Customer PO % for Quote % [xtuple: convertQuote, -8, %, %]',
+                      _ponumber, _qunumber,
+                      _ponumber, _qunumber;
     END IF;
   END IF;
   
@@ -180,7 +189,7 @@ BEGIN
     AND   (comment_source_id=pQuheadid) );
 
   FOR _r IN SELECT quitem.*,
-                   quhead_number, quhead_prj_id,
+                   quhead_number, quhead_prj_id, quhead_saletype_id,
                    itemsite_item_id, itemsite_leadtime,
                    itemsite_createsopo, itemsite_createsopr,
                    item_type, COALESCE(quitem_itemsrc_id, itemsrc_id, -1) AS itemsrcid
@@ -215,7 +224,8 @@ BEGIN
 
     IF (fetchMetricBool('enablextcommissionission')) THEN
       PERFORM xtcommission.getSalesReps(quhead_cust_id, quhead_shipto_id,
-                                        _r.itemsite_item_id, _r.quitem_price,
+                                        _r.itemsite_item_id, _r.quhead_saletype_id,
+                                        _r.quitem_price, _r.quitem_custprice,
                                         _soitemid, 'SalesItem')
       FROM quhead
       WHERE (quhead_id=pQuheadid);
@@ -242,8 +252,10 @@ BEGIN
     IF (_r.quitem_createorder) THEN
 
       IF (_r.item_type IN ('M')) THEN
-        SELECT createWo( CAST(_r.quhead_number AS INTEGER), supply.itemsite_id, 1, (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
-                         _r.itemsite_leadtime, _r.quitem_scheddate, _r.quitem_memo, 'S', _soitemid, _r.quhead_prj_id ) INTO _orderId
+        SELECT createWo( CAST(_soNum AS INTEGER), supply.itemsite_id, 1,
+                         (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
+                         _r.itemsite_leadtime, _r.quitem_scheddate, _r.quitem_memo,
+                         'S', _soitemid, _r.quhead_prj_id ) INTO _orderId
         FROM itemsite sold, itemsite supply
         WHERE ((sold.itemsite_item_id=supply.itemsite_item_id)
          AND (supply.itemsite_warehous_id=_r.quitem_order_warehous_id)
@@ -258,7 +270,8 @@ BEGIN
            AND  (charass_target_id=_r.quitem_id));
 
       ELSIF ( (_r.item_type IN ('P', 'O')) AND (_r.itemsite_createsopr) ) THEN
-        SELECT createPr( CAST(_r.quhead_number AS INTEGER), _r.quitem_itemsite_id, (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
+        SELECT createPr( CAST(_soNum AS INTEGER), _r.quitem_itemsite_id,
+                         (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
                          _r.quitem_scheddate, '', 'S', _soitemid ) INTO _orderId;
         _orderType := 'R';
         UPDATE pr SET pr_prj_id=_r.quhead_prj_id WHERE pr_id=_orderId;
index 5c68dc2..22c8c21 100644 (file)
@@ -4,6 +4,8 @@ CREATE OR REPLACE FUNCTION convertQuoteToInvoice(INTEGER) RETURNS INTEGER AS $$
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
   pQuheadid ALIAS FOR $1;
+  _qunumber TEXT;
+  _ponumber TEXT;
   _iheadid INTEGER;
   _iitemid INTEGER;
   _orderid INTEGER;
@@ -67,17 +69,47 @@ BEGIN
   END IF;
 
 -- PO/blanket PO checks
+  IF (_usespos) THEN
+    SELECT quhead_number, COALESCE(quhead_custponumber, ''), invchead_id INTO _qunumber, _ponumber, _iheadid
+    FROM quhead LEFT OUTER JOIN invchead ON ( (invchead_cust_id=quhead_cust_id) AND
+                                              (UPPER(invchead_ponumber)=UPPER(quhead_custponumber)) )
+    WHERE (quhead_id=pQuheadid);
+    IF (_ponumber = '') THEN
+      RAISE EXCEPTION 'Customer PO required for Quote % [xtuple: convertQuote, -7, %]',
+                      _qunumber, _qunumber;
+    END IF;
+  
+    IF ( (NOT _blanketpos) AND (_iheadid IS NOT NULL) ) THEN
+      RAISE EXCEPTION 'Duplicate Customer PO % for Quote % [xtuple: convertQuote, -8, %, %]',
+                      _ponumber, _qunumber,
+                      _ponumber, _qunumber;
+    END IF;
+  END IF;
+  
 
+  IF (_usespos) THEN
+    SELECT quhead_number INTO _qunumber
+    FROM quhead
+    WHERE (quhead_id=pQuheadid)
+      AND (COALESCE(quhead_custponumber, '') = '');
+    IF (FOUND) THEN
+      RAISE EXCEPTION 'Customer PO required for Quote % [xtuple: convertQuote, -7, %]',
+                      _qunumber, _qunumber;
+    END IF;
+  END IF;
+  
   IF ( (_usespos) AND (NOT _blanketpos) ) THEN
-    PERFORM invchead_id
+    SELECT quhead_number, quhead_custponumber INTO _qunumber, _ponumber
     FROM quhead JOIN invchead ON ( (invchead_cust_id=quhead_cust_id) AND
-                                 (UPPER(invchead_custponumber)=UPPER(quhead_custponumber)) )
+                                   (UPPER(invchead_ponumber)=UPPER(quhead_custponumber)) )
     WHERE (quhead_id=pQuheadid);
     IF (FOUND) THEN
-      RAISE EXCEPTION 'Duplicate Customer PO';
+      RAISE EXCEPTION 'Duplicate Customer PO % for Quote % [xtuple: convertQuote, -8, %, %]',
+                      _ponumber, _qunumber,
+                      _ponumber, _qunumber;
     END IF;
   END IF;
-
+  
 --Check to see if an invoice exists with the quote number
   
   PERFORM quhead_number, invchead_id 
@@ -182,7 +214,7 @@ BEGIN
 */
 
   FOR _r IN SELECT quitem.*,
-                   quhead_number, quhead_prj_id,
+                   quhead_number, quhead_prj_id, quhead_saletype_id,
                    itemsite_item_id, itemsite_leadtime,
                    itemsite_createsopo, itemsite_createsopr,
                    item_type, COALESCE(quitem_itemsrc_id, itemsrc_id, -1) AS itemsrcid
@@ -220,7 +252,8 @@ BEGIN
 
     IF (fetchMetricBool('enablextcommissionission')) THEN
       PERFORM xtcommission.getSalesReps(quhead_cust_id, quhead_shipto_id,
-                                        _r.itemsite_item_id, _r.quitem_price,
+                                        _r.itemsite_item_id, _r.quhead_saletype_id,
+                                        _r.quitem_price, _r.quitem_custprice,
                                         _iitemid, 'InvoiceItem')
       FROM quhead
       WHERE (quhead_id=pQuheadid);
index 7a8e316..764f5b8 100644 (file)
@@ -1,24 +1,22 @@
-CREATE OR REPLACE FUNCTION copyItemSite(pitemsiteid INTEGER,
-                                        pdestwhsid INTEGER) RETURNS INTEGER AS $$
+CREATE OR REPLACE FUNCTION copyItemSite(pItemsiteid INTEGER,
+                                        pDestWhsid INTEGER) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
 -- See www.xtuple.com/CPAL for the full text of the software license.
 
 BEGIN
 
-  RETURN copyItemSite(pitemsiteid, pdestwhsid, NULL);
+  RETURN copyItemSite(pItemsiteid, pDestWhsid, NULL);
 
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
 
 
-CREATE OR REPLACE FUNCTION copyItemSite(pitemsiteid INTEGER,
-                                        pdestwhsid INTEGER,
-                                        pdestitemid INTEGER) RETURNS INTEGER AS $$
+CREATE OR REPLACE FUNCTION copyItemSite(pItemsiteid INTEGER,
+                                        pDestWhsid INTEGER,
+                                        pDestItemid INTEGER) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pitemsiteid ALIAS FOR $1;
-  pdestwhsid  ALIAS FOR $2;
   _destwhs  whsinfo%ROWTYPE;
   _new    itemsite%ROWTYPE;
   _supplywarehousid INTEGER := NULL;
@@ -27,16 +25,16 @@ BEGIN
   -- make a copy of the old itemsite
   SELECT * INTO _new
   FROM itemsite
-  WHERE (itemsite_id=pitemsiteid);
+  WHERE (itemsite_id=pItemsiteid);
   IF (NOT FOUND) THEN
     RETURN -1;
   END IF;
 
   -- if there is no dest warehouse then perhaps the user is manually copying it
-  IF (pdestwhsid IS NOT NULL) THEN
+  IF (pDestWhsid IS NOT NULL) THEN
     SELECT * INTO _destwhs
     FROM whsinfo
-    WHERE (warehous_id=pdestwhsid);
+    WHERE (warehous_id=pDestWhsid);
     IF (NOT FOUND) THEN
       RETURN -2;
     END IF;
@@ -48,9 +46,9 @@ BEGIN
 
   SELECT itemsite_id INTO _new.itemsite_id
   FROM itemsite
-  WHERE ((itemsite_item_id=COALESCE(pdestitemid, _new.itemsite_item_id))
-    AND  (itemsite_warehous_id=pdestwhsid OR
-    (itemsite_warehous_id IS NULL AND pdestwhsid IS NULL)));
+  WHERE ((itemsite_item_id=COALESCE(pDestItemid, _new.itemsite_item_id))
+    AND  (itemsite_warehous_id=pDestWhsid OR
+    (itemsite_warehous_id IS NULL AND pDestWhsid IS NULL)));
   IF (FOUND) THEN
     RETURN _new.itemsite_id;
   END IF;
@@ -64,18 +62,17 @@ BEGIN
       SELECT itemsite_id INTO _new.itemsite_supply_itemsite_id
       FROM itemsite
       WHERE (itemsite_warehous_id=_supplywarehousid)
-        AND (itemsite_item_id=pdestitemid);
+        AND (itemsite_item_id=pDestItemid);
     END IF;
   END IF;
 
   -- now override the things we know have to change
   _new.itemsite_id                   := NEXTVAL('itemsite_itemsite_id_seq');
-  _new.itemsite_warehous_id          := pdestwhsid;
+  _new.itemsite_warehous_id          := pDestWhsid;
   _new.itemsite_qtyonhand            := 0;
   _new.itemsite_value                := 0;
   _new.itemsite_datelastcount        := NULL;
   _new.itemsite_datelastused         := NULL;
-  _new.itemsite_nnqoh                := 0;
   _new.itemsite_location_id          := -1;
   _new.itemsite_recvlocation_id      := -1;
   _new.itemsite_issuelocation_id     := -1;
@@ -111,7 +108,6 @@ BEGIN
     _new.itemsite_location           := NULL;
     _new.itemsite_location_comments  := NULL;
     _new.itemsite_notes              := 'Transit Warehouse';
-    _new.itemsite_nnqoh              := 0;
     _new.itemsite_createwo           := FALSE;
     _new.itemsite_costcat_id         := _destwhs.warehous_costcat_id;
     _new.itemsite_supply_itemsite_id := NULL;
@@ -138,7 +134,7 @@ BEGIN
     itemsite_soldranking,            itemsite_createpr,
     itemsite_location,               itemsite_location_comments,
     itemsite_notes,                  itemsite_perishable,
-    itemsite_nnqoh,                  itemsite_autoabcclass,
+    itemsite_autoabcclass,
     itemsite_ordergroup,             itemsite_disallowblankwip,
     itemsite_maxordqty,              itemsite_mps_timefence,
     itemsite_createwo,               itemsite_warrpurc,
@@ -150,7 +146,7 @@ BEGIN
     itemsite_location_dist,          itemsite_recvlocation_dist,
     itemsite_issuelocation_dist
   ) VALUES (
-    _new.itemsite_id,                COALESCE(pdestitemid, _new.itemsite_item_id),
+    _new.itemsite_id,                COALESCE(pDestItemid, _new.itemsite_item_id),
     _new.itemsite_warehous_id,         _new.itemsite_qtyonhand,
     _new.itemsite_costmethod,        _new.itemsite_value,
     _new.itemsite_reorderlevel,      _new.itemsite_ordertoqty,
@@ -170,7 +166,7 @@ BEGIN
     _new.itemsite_soldranking,         _new.itemsite_createpr,
     _new.itemsite_location,          _new.itemsite_location_comments,
     _new.itemsite_notes,             _new.itemsite_perishable,
-    _new.itemsite_nnqoh,             _new.itemsite_autoabcclass,
+    _new.itemsite_autoabcclass,
     _new.itemsite_ordergroup,        _new.itemsite_disallowblankwip,
     _new.itemsite_maxordqty,         _new.itemsite_mps_timefence,
     _new.itemsite_createwo,          _new.itemsite_warrpurc,
@@ -185,4 +181,4 @@ BEGIN
 
   RETURN _new.itemsite_id;
 END;
-$$ LANGUAGE 'plpgsql';
\ No newline at end of file
+$$ LANGUAGE plpgsql;
\ No newline at end of file
index c4b42cd..edbc609 100644 (file)
@@ -1,8 +1,7 @@
-CREATE OR REPLACE FUNCTION deleteItemSite(INTEGER) RETURNS INTEGER AS $$
+CREATE OR REPLACE FUNCTION deleteItemSite(pItemsiteid INTEGER) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemsiteid ALIAS FOR $1;
   _result INTEGER;
   _lotserial BOOLEAN;
   _bbom BOOLEAN;
@@ -11,7 +10,7 @@ DECLARE
 
 BEGIN
 
-  IF ( ( SELECT ( (itemsite_qtyonhand <> 0) OR (itemsite_nnqoh <> 0) )
+  IF ( ( SELECT (itemsite_qtyonhand <> 0)
          FROM itemsite
          WHERE (itemsite_id=pItemsiteid) ) ) THEN
     RETURN -9;
@@ -210,4 +209,4 @@ BEGIN
   RETURN 0;
 
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index 0eafa94..5a37354 100644 (file)
@@ -1,6 +1,9 @@
 CREATE OR REPLACE FUNCTION detailedNNQOH(INTEGER, BOOLEAN) RETURNS NUMERIC AS '
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
+--
+-- Deprecated
+--
 DECLARE
   pItemsiteid ALIAS FOR $1;
   pABS ALIAS FOR $2;
index aea3e77..d18a526 100644 (file)
@@ -1,30 +1,27 @@
-CREATE OR REPLACE FUNCTION detailedQOH(INTEGER, BOOLEAN) RETURNS NUMERIC AS '
+CREATE OR REPLACE FUNCTION detailedQOH(pItemsiteid INTEGER,
+                                       pABS BOOLEAN) RETURNS NUMERIC AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemsiteid ALIAS FOR $1;
-  pABS ALIAS FOR $2;
   _qoh NUMERIC;
 
 BEGIN
 
   IF (pABS) THEN
     SELECT SUM(noNeg(itemloc_qty)) INTO _qoh
-    FROM itemloc LEFT OUTER JOIN location ON (itemloc_location_id=location_id)
-    WHERE ( ( (location_id IS NULL) OR (location_netable) )
-     AND (itemloc_itemsite_id=pItemsiteid) );
+    FROM itemloc
+    WHERE (itemloc_itemsite_id=pItemsiteid);
   ELSE
     SELECT SUM(itemloc_qty) INTO _qoh
-    FROM itemloc LEFT OUTER JOIN location ON (itemloc_location_id=location_id)
-    WHERE ( ( (location_id IS NULL) OR (location_netable) )
-     AND (itemloc_itemsite_id=pItemsiteid) );
+    FROM itemloc
+    WHERE (itemloc_itemsite_id=pItemsiteid);
   END IF;
 
   IF (_qoh IS NULL) THEN
-    _qoh := 0;
+    _qoh := 0.0;
   END IF;
 
   RETURN _qoh;
 
 END;
-' LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index 01ed663..0165aab 100644 (file)
@@ -1,8 +1,7 @@
-CREATE OR REPLACE FUNCTION distributeItemlocSeries(INTEGER) RETURNS INTEGER AS $$
+CREATE OR REPLACE FUNCTION distributeItemlocSeries(pItemlocSeries INTEGER) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemlocSeries   ALIAS FOR $1;
   _distCounter     INTEGER;
   _itemlocdist     RECORD;
   _itemlocid       INTEGER;
@@ -135,50 +134,6 @@ BEGIN
         WHERE (itemloc_id=_itemlocid);
       END IF;
 
---  Adjust QOH if this itemlocdist is to/from a non-netable location
-      IF ( SELECT (NOT location_netable)
-           FROM itemloc, location
-           WHERE ( (itemloc_location_id=location_id)
-            AND (itemloc_id=_itemlocid) ) ) THEN
-
---  Record the netable->non-netable (or visaveras) invhist
-        SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
-        INSERT INTO invhist
-        ( invhist_id, invhist_itemsite_id, 
-          invhist_transtype, invhist_invqty,
-          invhist_qoh_before, invhist_qoh_after,
-          invhist_docnumber, invhist_comments,
-          invhist_invuom, invhist_unitcost,
-          invhist_costmethod, invhist_value_before, invhist_value_after,
-          invhist_series ) 
-        SELECT _invhistid, itemsite_id, 
-               'NN', (_itemlocdist.qty * -1),
-               itemsite_qtyonhand, (itemsite_qtyonhand - _itemlocdist.qty),
-               invhist_docnumber, invhist_comments,
-               uom_name, stdCost(item_id),
-               itemsite_costmethod, itemsite_value,
-               (itemsite_value + (_itemlocdist.qty * -1 * CASE WHEN(itemsite_costmethod='A') THEN avgcost(itemsite_id)
-                                                               ELSE stdCost(itemsite_item_id)
-                                                          END)),
-               _itemlocdist.series
-        FROM item, itemsite, invhist, uom
-        WHERE ((itemsite_item_id=item_id)
-         AND (item_inv_uom_id=uom_id)
-         AND (itemsite_controlmethod <> 'N')
-         AND (itemsite_id=_itemlocdist.itemsiteid)
-         AND (invhist_id=_itemlocdist.invhistid));
-
---  Adjust the parent itemsite
-        IF (NOT _itemlocdist.itemsite_freeze) THEN
-          UPDATE itemsite
-          SET itemsite_qtyonhand = (itemsite_qtyonhand - _itemlocdist.qty),
-              itemsite_nnqoh = (itemsite_nnqoh + _itemlocdist.qty)
-          FROM itemloc
-          WHERE ((itemloc_itemsite_id=itemsite_id)
-           AND (itemloc_id=_itemlocid));
-        END IF;
-      END IF;
-
     END IF;
 
 --  If, after the distribution, the target itemloc_qty = 0, delete the itemloc
@@ -197,4 +152,4 @@ BEGIN
   RETURN _distCounter;
 
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index 5d3fad9..61d8577 100644 (file)
@@ -1,8 +1,7 @@
-CREATE OR REPLACE FUNCTION distributeToLocations(INTEGER) RETURNS INTEGER AS $$
+CREATE OR REPLACE FUNCTION distributeToLocations(pItemlocdistid INTEGER) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemlocdistid ALIAS FOR $1;
   _distCounter INTEGER;
   _itemlocdist RECORD;
   _itemlocid INTEGER;
@@ -147,49 +146,6 @@ BEGIN
       END IF;
     END IF;
 
---  Adjust QOH if this itemlocdist is to/from a non-netable location
-    IF ( SELECT (NOT location_netable)
-         FROM itemloc, location
-         WHERE ((itemloc_location_id=location_id)
-          AND (itemloc_id=_itemlocid)) ) THEN
-
---  Record the invhist record for the netable->non-netable (or visaversa)
-      INSERT INTO invhist
-      ( invhist_itemsite_id,
-        invhist_transtype, invhist_invqty,
-        invhist_qoh_before, invhist_qoh_after,
-        invhist_docnumber, invhist_comments,
-        invhist_invuom, invhist_unitcost,
-        invhist_costmethod, invhist_value_before, invhist_value_after,
-        invhist_series )
-      SELECT itemsite_id,
-             'NN', (_itemlocdist.qty * -1),
-             itemsite_qtyonhand, (itemsite_qtyonhand - _itemlocdist.qty),
-             invhist_docnumber, invhist_comments,
-             uom_name, stdCost(item_id),
-             itemsite_costmethod, itemsite_value,
-             (itemsite_value + (_itemlocdist.qty * -1 * CASE WHEN(itemsite_costmethod='A') THEN avgcost(itemsite_id)
-                                                             ELSE stdCost(itemsite_item_id)
-                                                        END)),
-             _itemlocdist.series
-      FROM item, itemsite, invhist, uom
-      WHERE ( (itemsite_item_id=item_id)
-       AND (item_inv_uom_id=uom_id)
-       AND (itemsite_controlmethod <> 'N')
-       AND (itemsite_id=_itemlocdist.itemsiteid)
-       AND (invhist_id=_itemlocdist.invhistid) );
-
---  Update the itemsite_qoh
-      IF (NOT _itemlocdist.itemsite_freeze) THEN
-        UPDATE itemsite
-        SET itemsite_qtyonhand = (itemsite_qtyonhand - _itemlocdist.qty),
-            itemsite_nnqoh = (itemsite_nnqoh + _itemlocdist.qty)
-        FROM itemloc
-        WHERE ((itemloc_itemsite_id=itemsite_id)
-         AND (itemloc_id=_itemlocid));
-      END IF;
-    END IF;
-
 --  Cache the running qty.
     _runningQty := _runningQty + _itemlocdist.qty;
 
@@ -226,4 +182,4 @@ BEGIN
   RETURN _distCounter;
 
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index 62da625..a9cd679 100644 (file)
@@ -22,7 +22,7 @@ BEGIN
                                              AND  (invcitem_item_id=itemsite_item_id)
                                              AND  (invcitem_warehous_id=itemsite_warehous_id)
                                              AND  (invcitem_linenumber=coitem_linenumber))) > 0)) THEN 'P'
-            WHEN (coitem_status='O' AND (itemsite_qtyonhand - qtyAllocated(itemsite_id, CURRENT_DATE)
+            WHEN (coitem_status='O' AND (qtyAvailable(itemsite_id) - qtyAllocated(itemsite_id, CURRENT_DATE)
                                          + qtyOrdered(itemsite_id, CURRENT_DATE))
                                           >= ((coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) * coitem_qty_invuomratio)) THEN 'R'
             ELSE coitem_status END
diff --git a/foundation-database/public/functions/importbankreccleared.sql b/foundation-database/public/functions/importbankreccleared.sql
new file mode 100644 (file)
index 0000000..4fddd3e
--- /dev/null
@@ -0,0 +1,182 @@
+
+CREATE OR REPLACE FUNCTION importBankrecCleared(pBankrecid INTEGER) RETURNS INTEGER AS $$
+-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _bankrecid INTEGER;
+  _result INTEGER := 0;
+  _cleared BOOLEAN;
+  _doctype TEXT;
+  _docid INTEGER := -1;
+  _bankadjid INTEGER := -1;
+  _debitbankadjtypeid INTEGER := -1;
+  _creditbankadjtypeid INTEGER := -1;
+  _b RECORD;
+  _r RECORD;
+
+BEGIN
+  -- cache some information
+  IF (pBankrecid = -1) THEN
+    _bankrecid := fetchMetricValue('ImportBankRecId');
+  ELSE
+    _bankrecid := pBankrecid;
+  END IF;
+
+  SELECT * INTO _b
+  FROM bankrec JOIN bankaccnt ON (bankaccnt_id=bankrec_bankaccnt_id)
+  WHERE (bankrec_id=_bankrecid);
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'bankrec not found';
+  END IF;
+  IF (_b.bankrec_posted) THEN
+    RAISE EXCEPTION 'bankrec already posted';
+  END IF;
+
+   _debitbankadjtypeid := fetchMetricValue('ImportBankRecDebitAdj');
+  IF (_debitbankadjtypeid = -1) THEN
+    RAISE EXCEPTION 'Metric ImportBankRecDebitAdj not defined [xtuple: reconcileBankAccount, -1]';
+  END IF;
+
+   _creditbankadjtypeid := fetchMetricValue('ImportBankRecCreditAdj');
+  IF (_creditbankadjtypeid = -1) THEN
+    RAISE EXCEPTION 'Metric ImportBankRecCreditAdj not defined [xtuple: reconcileBankAccount, -2]';
+  END IF;
+
+  -- loop thru bankrecimport and toggle cleared items
+  FOR _r IN
+  SELECT *,
+         COALESCE(bankrecimport_debit_amount, 0.0) AS debit,
+         COALESCE(bankrecimport_credit_amount, 0.0) AS credit
+  FROM bankrecimport
+-- TODO how to handle multiple bank accounts
+--  WHERE (bankrecimport_?=_b.bankaccnt=?)
+  LOOP
+
+    -- TODO how to handle duplicate document numbers
+    -- TODO how to handle amount differences
+    -- TODO add support for Project Accounting (sltrans)
+
+    IF ( (_r.debit > 0.0) AND (_r.credit > 0.0) ) THEN
+      RAISE NOTICE 'Bankrecimport % cannot determine if debit or credit', _r.bankrecimport_reference;
+      CONTINUE;
+    END IF;
+
+    IF (_r.debit > 0.0) THEN
+
+      -- handle receipts
+
+      SELECT cashrcpt_id INTO _docid
+      FROM cashrcpt
+      WHERE (cashrcpt_docnumber=_r.bankrecimport_reference)
+        AND (cashrcpt_posted)
+        AND (NOT cashrcpt_void)
+      -- TODO workaround for duplicates
+      ORDER BY cashrcpt_id DESC
+      LIMIT 1;
+      IF (FOUND) THEN
+        SELECT toggleBankrecCleared(_b.bankrec_id, 'GL', gltrans_id,
+                                    cashrcpt_curr_rate, _r.debit,
+                                    _r.bankrecimport_effdate) INTO _cleared
+        FROM gltrans LEFT OUTER JOIN bankrecitem ON (bankrecitem_source='GL' AND
+                                                     bankrecitem_source_id=gltrans_id)
+        WHERE (gltrans_source='A/R')
+          AND (gltrans_doctype='CR')
+          AND (gltrans_misc_id=_docid)
+          AND (NOT gltrans_rec)
+          AND (gltrans_accnt_id=_b.bankaccnt_accnt_id)
+          AND (NOT COALESCE(bankrecitem_cleared, FALSE));
+      ELSE
+
+        -- create and toggle bank adjustment
+        -- TODO define bank adjustment names
+
+        _bankadjid := -1;
+        SELECT bankadj_id INTO _bankadjid
+        FROM bankadj JOIN bankadjtype ON (bankadjtype_id=bankadj_bankadjtype_id)
+        WHERE (bankadjtype_id=_debitbankadjtypeid)
+          AND (bankadj_docnumber=_r.bankrecimport_reference)
+          AND (bankadj_bankaccnt_id=_b.bankaccnt_id);
+        IF (NOT FOUND) THEN
+          INSERT INTO bankadj
+            (bankadj_bankaccnt_id, bankadj_bankadjtype_id, bankadj_date,
+             bankadj_docnumber, bankadj_amount, bankadj_notes,
+             bankadj_curr_id)
+          VALUES
+            (_b.bankaccnt_id, _debitbankadjtypeid, _r.bankrecimport_effdate,
+             _r.bankrecimport_reference, _r.debit, 'Import Bankrec Adjustment',
+             _b.bankaccnt_curr_id)
+          RETURNING bankadj_id INTO _bankadjid;
+        END IF;
+
+        SELECT toggleBankrecCleared(_b.bankrec_id, 'AD', _bankadjid,
+                                    1.0, _r.debit,
+                                    _r.bankrecimport_effdate) INTO _cleared
+        FROM bankadj LEFT OUTER JOIN bankrecitem ON (bankrecitem_source='AD' AND
+                                                     bankrecitem_source_id=bankadj_id)
+        WHERE (bankadj_id=_bankadjid)
+          AND (NOT COALESCE(bankrecitem_cleared, FALSE));
+      END IF;
+
+      -- done with receipts
+
+    ELSE
+
+      -- handle checks
+
+      SELECT checkhead_id INTO _docid
+      FROM checkhead
+      WHERE (checkhead_number::TEXT=_r.bankrecimport_reference)
+        AND (checkhead_posted)
+        AND (NOT checkhead_void);
+      IF (FOUND) THEN
+        SELECT toggleBankrecCleared(_b.bankrec_id, 'GL', gltrans_id,
+                                    checkhead_curr_rate, _r.credit,
+                                    _r.bankrecimport_effdate) INTO _cleared
+        FROM gltrans LEFT OUTER JOIN bankrecitem ON (bankrecitem_source='GL' AND
+                                                     bankrecitem_source_id=gltrans_id)
+        WHERE (gltrans_source='A/P')
+          AND (gltrans_doctype='CK')
+          AND (gltrans_misc_id=_docid)
+          AND (NOT gltrans_rec)
+          AND (gltrans_accnt_id=_b.bankaccnt_accnt_id)
+          AND (NOT COALESCE(bankrecitem_cleared, FALSE));
+      ELSE
+
+        -- create and toggle bank adjustment
+        -- TODO define bank adjustment names
+
+        _bankadjid := -1;
+        SELECT bankadj_id INTO _bankadjid
+        FROM bankadj JOIN bankadjtype ON (bankadjtype_id=bankadj_bankadjtype_id)
+        WHERE (bankadjtype_id=_creditbankadjtypeid)
+          AND (bankadj_docnumber=_r.bankrecimport_reference);
+        IF (NOT FOUND) THEN
+          INSERT INTO bankadj
+            (bankadj_bankaccnt_id, bankadj_bankadjtype_id, bankadj_date,
+             bankadj_docnumber, bankadj_amount, bankadj_notes,
+             bankadj_curr_id)
+          VALUES
+            (_b.bankaccnt_id, _creditbankadjtypeid, _r.bankrecimport_effdate,
+             _r.bankrecimport_reference, _r.credit, 'Import Bankrec Adjustment',
+             _b.bankaccnt_curr_id)
+          RETURNING bankadj_id INTO _bankadjid;
+        END IF;
+
+        SELECT toggleBankrecCleared(_b.bankrec_id, 'AD', _bankadjid,
+                                    1.0, _r.credit,
+                                    _r.bankrecimport_effdate) INTO _cleared
+        FROM bankadj LEFT OUTER JOIN bankrecitem ON (bankrecitem_source='AD' AND
+                                                     bankrecitem_source_id=_bankadjid)
+        WHERE (NOT COALESCE(bankrecitem_cleared, FALSE));
+      END IF;
+
+      -- done with checks
+
+    END IF;
+
+  END LOOP;
+
+  RETURN _result;
+END;
+$$ LANGUAGE 'plpgsql';
+
index 66243e1..7c40758 100644 (file)
@@ -24,7 +24,7 @@ BEGIN
     --get top level works orders
     FOR _x IN
        SELECT wo_id,wo_number,wo_subnumber,wo_status,wo_startdate,
-         wo_duedate,wo_adhoc,wo_itemsite_id,itemsite_qtyonhand,
+         wo_duedate,wo_adhoc,wo_itemsite_id,qtyAvailable(itemsite_id) AS availableqoh,
          wo_qtyord,wo_qtyrcv,wo_prodnotes, item_number,
          item_descrip1, item_descrip2, item_listprice, uom_name
        FROM wo, itemsite, item, uom     
@@ -47,7 +47,7 @@ BEGIN
         _row.wodata_itemsite_id := _x.wo_itemsite_id;
         _row.wodata_custprice := _x.item_listprice;
         _row.wodata_listprice := _x.item_listprice;
-        _row.wodata_qoh := _x.itemsite_qtyonhand;
+        _row.wodata_qoh := _x.availableqoh;
         _row.wodata_short := noneg(_x.wo_qtyord - _x.wo_qtyrcv);
         _row.wodata_qtyrcv := _x.wo_qtyrcv;   
         _row.wodata_qtyordreq := _x.wo_qtyord;   
@@ -149,7 +149,7 @@ BEGIN
     _level := (plevel + 1);    
     --find all WO with the ordid of the next level up
     _qry := 'SELECT wo_id,wo_number,wo_subnumber,wo_status,wo_startdate,wo_duedate,
-         wo_adhoc,wo_itemsite_id,itemsite_qtyonhand,wo_qtyord,wo_qtyrcv, wo_prodnotes,
+         wo_adhoc,wo_itemsite_id,qtyAvailable(itemsite_id) AS availableqoh,wo_qtyord,wo_qtyrcv, wo_prodnotes,
          item_number,item_descrip1, item_descrip2, item_listprice, uom_name,
          womatl_qtyiss, womatl_scrap, womatl_wooper_id
        FROM itemsite,  wo, item, uom, womatl 
@@ -184,7 +184,7 @@ BEGIN
         _row.wodata_itemsite_id := _x.wo_itemsite_id;        
         _row.wodata_custprice := _x.item_listprice;
         _row.wodata_listprice := _x.item_listprice;
-        _row.wodata_qoh := _x.itemsite_qtyonhand;
+        _row.wodata_qoh := _x.availableqoh;
         _row.wodata_short := noneg(_x.wo_qtyord - _x.wo_qtyrcv);
         _row.wodata_qtyiss := _x.womatl_qtyiss;  
         _row.wodata_qtyrcv := _x.wo_qtyrcv;   
index 53042e3..8155994 100644 (file)
@@ -40,7 +40,7 @@ BEGIN
 
   _qry := 'SELECT womatl_id, wo_number, wo_subnumber, 
       wo_startdate, womatl_duedate, womatl_itemsite_id,
-      itemsite_qtyonhand, womatl_qtyreq, womatl_qtyiss,
+      qtyAvailable(itemsite_id) AS availableqoh, womatl_qtyreq, womatl_qtyiss,
       womatl_qtyper, womatl_qtyreq, womatl_scrap,
       womatl_ref, womatl_notes, womatl_price, item_listprice,
       item_number, item_descrip1, item_descrip2,
@@ -78,11 +78,11 @@ BEGIN
     _subrow.wodata_itemsite_id := _subx.womatl_itemsite_id;    
     _subrow.wodata_custprice := _subx.womatl_price;
     _subrow.wodata_listprice := _subx.item_listprice;
-    _subrow.wodata_qoh := _subx.itemsite_qtyonhand;
-    IF((_subx.itemsite_qtyonhand > (_subx.womatl_qtyreq - _subx.womatl_qtyiss))) THEN
+    _subrow.wodata_qoh := _subx.availableqoh;
+    IF((_subx.availableqoh > (_subx.womatl_qtyreq - _subx.womatl_qtyiss))) THEN
       _subrow.wodata_short := 0;
     ELSE
-      _subrow.wodata_short := (_subx.womatl_qtyreq - _subx.womatl_qtyiss) -  _subx.itemsite_qtyonhand;
+      _subrow.wodata_short := (_subx.womatl_qtyreq - _subx.womatl_qtyiss) -  _subx.availableqoh;
     END IF;
     _subrow.wodata_qtyper := _subx.womatl_qtyper;
     _subrow.wodata_qtyiss := _subx.womatl_qtyiss;         
index 6c796f7..b1f2e74 100644 (file)
@@ -1,9 +1,8 @@
-CREATE OR REPLACE FUNCTION initialDistribution(INTEGER, INTEGER) RETURNS INTEGER  AS $$
+CREATE OR REPLACE FUNCTION initialDistribution(pItemsiteid INTEGER,
+                                               pLocationid INTEGER) RETURNS INTEGER  AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemsiteid ALIAS FOR $1;
-  pLocationid ALIAS FOR $2;
   _itemlocid INTEGER;
   _invhistid INTEGER;
   _itemlocSeries INTEGER;
@@ -65,37 +64,6 @@ BEGIN
       ( _invhistid, pLocationid, _r.itemloc_ls_id,
         _r.itemloc_qty, 0, _r.itemloc_qty );
 
---  Adjust QOH if this itemlocdist is to/from a non-netable location
-      IF ( SELECT (NOT location_netable)
-           FROM location
-           WHERE (location_id=pLocationid) ) THEN
-
-        INSERT INTO invhist
-        ( invhist_itemsite_id, invhist_series,
-          invhist_transtype, invhist_invqty,
-          invhist_qoh_before, invhist_qoh_after,
-          invhist_comments,
-          invhist_invuom, invhist_unitcost,
-          invhist_costmethod, invhist_value_before, invhist_value_after  ) 
-        SELECT itemsite_id, _itemlocSeries,
-               'NN', (_r.itemloc_qty * -1),
-               _r.itemloc_qty, 0,
-               'Initial Distribution',
-               uom_name, stdCost(item_id),
-               itemsite_costmethod, itemsite_value, itemsite_value
-        FROM itemsite, item, uom
-        WHERE ( (itemsite_item_id=item_id)
-         AND (item_inv_uom_id=uom_id)
-         AND (itemsite_controlmethod <> 'N')
-         AND (itemsite_id=pItemsiteid) );
-
-        UPDATE itemsite
-        SET itemsite_nnqoh = (itemsite_nnqoh + _r.itemloc_qty),
-            itemsite_qtyonhand = (itemsite_qtyonhand - _r.itemloc_qty) 
-        WHERE (itemsite_id=pItemsiteid);
-
-      END IF;
-
     END LOOP;
 
   ELSE
@@ -144,43 +112,9 @@ BEGIN
     FROM itemsite
     WHERE (itemsite_id=pItemsiteid);
 
---  Adjust QOH if this itemlocdist is to/from a non-netable location
-    IF ( SELECT (NOT location_netable)
-         FROM location
-         WHERE (location_id=pLocationid) ) THEN
-
-      INSERT INTO invhist
-      ( invhist_itemsite_id, invhist_series,
-        invhist_transtype, invhist_invqty,
-        invhist_qoh_before, invhist_qoh_after,
-        invhist_comments,
-        invhist_invuom, invhist_unitcost,
-        invhist_costmethod, invhist_value_before, invhist_value_after  ) 
-      SELECT itemsite_id, _itemlocSeries,
-             'NN', (itemloc_qty * -1),
-             itemloc_qty, 0,
-             'Initial Distribution',
-             uom_name, stdCost(item_id),
-             itemsite_costmethod, itemsite_value, itemsite_value
-      FROM itemloc, itemsite, item, uom
-      WHERE ( (itemsite_item_id=item_id)
-       AND (item_inv_uom_id=uom_id)
-       AND (itemsite_controlmethod <> 'N')
-       AND (itemloc_itemsite_id=itemsite_id)
-       AND (itemloc_id=_itemlocid) );
-
-      UPDATE itemsite
-      SET itemsite_nnqoh = itemsite_qtyonhand,
-          itemsite_qtyonhand = 0 
-      FROM itemloc
-      WHERE ( (itemloc_itemsite_id=itemsite_id)
-       AND (itemloc_id=_itemlocid) );
-
-    END IF;
-
   END IF;
 
   RETURN _itemlocid;
 
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index 4469198..77e3340 100644 (file)
@@ -1,8 +1,7 @@
-CREATE OR REPLACE FUNCTION itemInventoryUOMInUse(INTEGER) RETURNS BOOLEAN AS '
+CREATE OR REPLACE FUNCTION itemInventoryUOMInUse(pItemid INTEGER) RETURNS BOOLEAN AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemid ALIAS FOR $1;
   _uomid INTEGER;
   _result INTEGER;
 BEGIN
@@ -20,7 +19,7 @@ BEGIN
 
   SELECT itemsite_id INTO _result
   FROM itemsite WHERE ( (itemsite_item_id=pItemid)
-                  AND   ((itemsite_qtyonhand <> 0) OR (itemsite_nnqoh <> 0)) )
+                  AND   (itemsite_qtyonhand <> 0) )
   LIMIT 1;
   IF (FOUND) THEN
     RETURN TRUE;
@@ -28,4 +27,4 @@ BEGIN
 
   RETURN FALSE;
 END;
-' LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index be98b98..71a87e2 100644 (file)
@@ -1,11 +1,10 @@
 SELECT dropIfExists('FUNCTION', 'postCountTag(integer, boolean, text)', 'public');
 
-CREATE OR REPLACE FUNCTION postCountTag(INTEGER, BOOLEAN) RETURNS INTEGER AS $$
+CREATE OR REPLACE FUNCTION postCountTag(pInvcntid INTEGER,
+                                        pThaw BOOLEAN) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pInvcntid ALIAS FOR $1;
-  pThaw ALIAS FOR $2;
   _avgCostingMethod TEXT;
   _invhistid INTEGER;
   _postDate TIMESTAMP;
@@ -243,8 +242,8 @@ BEGIN
 --  Avoid negative value when average cost item
     UPDATE itemsite
     SET itemsite_qtyonhand=_p.invcnt_qoh_after,
-        itemsite_nnqoh = 0,
-        itemsite_value = CASE WHEN ((itemsite_costmethod='A') AND (_p.itemsite_value + (_p.cost * (_p.invcnt_qoh_after - itemsite_qtyonhand))) < 0.0) THEN 0.0
+        itemsite_value = CASE WHEN ((itemsite_costmethod='A') AND
+                                    (_p.itemsite_value + (_p.cost * (_p.invcnt_qoh_after - itemsite_qtyonhand))) < 0.0) THEN 0.0
                               ELSE (_p.itemsite_value + (_p.cost * (_p.invcnt_qoh_after - itemsite_qtyonhand)))
                          END,
         itemsite_datelastcount=_postDate
@@ -263,7 +262,8 @@ BEGIN
     END IF;
 
 --  Distribute to G/L
-    PERFORM insertGLTransaction( 'I/M', 'CT', _p.invcnt_tagnumber, ('Post Count Tag #' || _p.invcnt_tagnumber || ' for Item ' || _p.item_number),
+    PERFORM insertGLTransaction( 'I/M', 'CT', _p.invcnt_tagnumber,
+                                 ('Post Count Tag #' || _p.invcnt_tagnumber || ' for Item ' || _p.item_number),
                                  costcat_adjustment_accnt_id, costcat_asset_accnt_id, _invhistid,
                                  ( (_p.invcnt_qoh_after - _p.itemsite_qtyonhand) * _p.cost), _postDate::DATE )
     FROM invcnt, itemsite, costcat
@@ -278,4 +278,4 @@ BEGIN
   END IF;
 
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index 94514b8..aaa0cd7 100644 (file)
@@ -1,9 +1,8 @@
-CREATE OR REPLACE FUNCTION postCountTagLocation(INTEGER, BOOLEAN) RETURNS INTEGER AS $$
+CREATE OR REPLACE FUNCTION postCountTagLocation(pInvcntid INTEGER,
+                                                pThaw BOOLEAN) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pInvcntid ALIAS FOR $1;
-  pThaw ALIAS FOR $2;
   _avgCostingMethod TEXT;
   _invhistid INTEGER;
   _postDate TIMESTAMP;
@@ -15,7 +14,6 @@ DECLARE
   _itemloc RECORD;
   _cntslip RECORD;
   _origLocQty NUMERIC;
-  _netable BOOLEAN;
   _lsid INTEGER;
 BEGIN
 
@@ -29,7 +27,7 @@ BEGIN
          itemsite_loccntrl, COALESCE(invcnt_location_id, -1) AS itemsite_location_id,
          CASE WHEN (itemsite_costmethod = 'N') THEN 0
               WHEN ( (itemsite_costmethod = 'A') AND
-                     ((itemsite_qtyonhand + itemsite_nnqoh) = 0) AND
+                     (itemsite_qtyonhand = 0.0) AND
                      (_avgCostingMethod = 'ACT') ) THEN actcost(itemsite_item_id)
               WHEN ( (itemsite_costmethod = 'A') AND
                      (_avgCostingMethod IN ('ACT', 'AVG')) ) THEN avgcost(itemsite_id)
@@ -46,15 +44,12 @@ BEGIN
     RETURN -9;
   END IF;
 
-  SELECT COALESCE(SUM(itemloc_qty),0.0), location_netable INTO _origLocQty,_netable
-    FROM itemloc,location
+  SELECT COALESCE(SUM(itemloc_qty),0.0) INTO _origLocQty
+    FROM itemloc
    WHERE ((itemloc_itemsite_id=_p.itemsite_id)
-     AND  (location_id=itemloc_location_id)
-     AND  (itemloc_location_id=_p.invcnt_location_id))
-   GROUP BY location_netable;
+     AND  (itemloc_location_id=_p.invcnt_location_id));
   IF (NOT FOUND) THEN
     _origLocQty := 0.0;
-    _netable := TRUE;
   END IF;
 
   SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
@@ -236,23 +231,13 @@ BEGIN
    AND (invcnt_id=pInvcntid) );
 
 --  Update the QOH
-  IF (_netable) THEN
-    UPDATE itemsite
-    SET itemsite_qtyonhand= itemsite_qtyonhand + (_p.invcnt_qoh_after - _origLocQty),
-        itemsite_datelastcount=_postDate
-    WHERE (itemsite_id=_p.itemsite_id);
-    UPDATE itemsite
-    SET itemsite_value =  (itemsite_qtyonhand + itemsite_nnqoh) * _p.cost
-    WHERE (itemsite_id=_p.itemsite_id);
-  ELSE
-    UPDATE itemsite
-    SET itemsite_nnqoh =  itemsite_nnqoh + (_p.invcnt_qoh_after - _origLocQty),
-        itemsite_datelastcount=_postDate
-    WHERE (itemsite_id=_p.itemsite_id);
-    UPDATE itemsite
-    SET itemsite_value =  (itemsite_qtyonhand + itemsite_nnqoh) * _p.cost
-    WHERE (itemsite_id=_p.itemsite_id);
-  END IF;
+  UPDATE itemsite
+  SET itemsite_qtyonhand= itemsite_qtyonhand + (_p.invcnt_qoh_after - _origLocQty),
+      itemsite_datelastcount=_postDate
+  WHERE (itemsite_id=_p.itemsite_id);
+  UPDATE itemsite
+  SET itemsite_value =  itemsite_qtyonhand * _p.cost
+  WHERE (itemsite_id=_p.itemsite_id);
  
 --  Post the detail, if any
   IF (_hasDetail) THEN
@@ -267,7 +252,8 @@ BEGIN
   END IF;
 
 --  Distribute to G/L
-  PERFORM insertGLTransaction( 'I/M', 'CT', _p.invcnt_tagnumber, ('Post Count Tag #' || _p.invcnt_tagnumber || ' for Item ' || _p.item_number),
+  PERFORM insertGLTransaction( 'I/M', 'CT', _p.invcnt_tagnumber,
+                               ('Post Count Tag #' || _p.invcnt_tagnumber || ' for Item ' || _p.item_number),
                                costcat_adjustment_accnt_id, costcat_asset_accnt_id, _invhistid,
                                ( (_p.invcnt_qoh_after - _origLocQty) * _p.cost), CURRENT_DATE )
   FROM invcnt, itemsite, costcat
@@ -277,4 +263,4 @@ BEGIN
 
   RETURN 0;
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index 9afe786..46f272f 100644 (file)
@@ -127,7 +127,7 @@ BEGIN
     (itemsite_qtyonhand + (_sense * pQty)),
     itemsite_costmethod, itemsite_value,
     -- sanity check to ensure that value = 0 when qtyonhand = 0
-    CASE WHEN ((itemsite_qtyonhand + (_sense * pQty)) + itemsite_nnqoh) = 0.0 THEN 0.0
+    CASE WHEN ((itemsite_qtyonhand + (_sense * pQty))) = 0.0 THEN 0.0
          ELSE itemsite_value + (_r.cost * _sense * pQty)
     END,
     pOrderType, pOrderNumber, pDocNumber, pComments,
diff --git a/foundation-database/public/functions/qtyatlocation.sql b/foundation-database/public/functions/qtyatlocation.sql
new file mode 100644 (file)
index 0000000..1c2ab13
--- /dev/null
@@ -0,0 +1,21 @@
+
+CREATE OR REPLACE FUNCTION qtyAtLocation(pItemsiteid INTEGER,
+                                         pLocationid INTEGER) RETURNS NUMERIC STABLE AS $$
+-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _qty         NUMERIC := 0.0;
+
+BEGIN
+  SELECT CASE WHEN (pLocationid IS NULL) THEN itemsite_qtyonhand
+              ELSE COALESCE(SUM(itemloc_qty), 0.0)
+         END INTO _qty
+    FROM itemsite LEFT OUTER JOIN itemloc ON (itemloc_itemsite_id=itemsite_id)
+   WHERE ((itemsite_id=pItemsiteid)
+     AND  (itemloc_location_id=pLocationid))
+  GROUP BY itemsite_qtyonhand;
+
+  RETURN _qty;
+
+END;
+$$ LANGUAGE plpgsql;
index 5ccbbea..2145d7b 100644 (file)
@@ -1,35 +1,78 @@
-CREATE OR REPLACE FUNCTION qtyAvailable(INTEGER, INTEGER) RETURNS NUMERIC AS '
+
+CREATE OR REPLACE FUNCTION qtyAvailable(pItemsiteId INTEGER) RETURNS NUMERIC STABLE AS $$
+-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _qty         NUMERIC = 0.0;
+
+BEGIN
+  _qty := qtyAvailable(pItemsiteId, TRUE);
+
+  RETURN _qty;
+
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION qtyAvailable(pItemsiteId INTEGER,
+                                        pUsable BOOLEAN) RETURNS NUMERIC STABLE AS $$
+-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _qty         NUMERIC = 0.0;
+
+BEGIN
+  IF (pUsable) THEN
+    -- Summarize itemloc qty for this itemsite/usable locations
+    -- or use itemsite_qtyonhand for regular/non-lot
+    SELECT COALESCE(SUM(itemloc_qty), itemsite_qtyonhand) INTO _qty
+      FROM itemsite LEFT OUTER JOIN itemloc ON (itemloc_itemsite_id=itemsite_id)
+                    LEFT OUTER JOIN location ON (location_id=itemloc_location_id)
+     WHERE (itemsite_id=pItemsiteId)
+       AND ((location_id IS NULL) OR (COALESCE(location_usable, true)))
+     GROUP BY itemsite_qtyonhand;
+  ELSE
+    -- Summarize itemloc qty for this itemsite/non-usable locations
+    SELECT COALESCE(SUM(itemloc_qty), 0.0) INTO _qty
+      FROM itemloc JOIN location ON (location_id=itemloc_location_id)
+     WHERE (itemloc_itemsite_id=pItemsiteId)
+       AND (NOT COALESCE(location_usable, true));
+  END IF;
+
+  RETURN _qty;
+
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION qtyAvailable(pItemsiteid INTEGER,
+                                        pLookAheadDays INTEGER) RETURNS NUMERIC STABLE AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemsiteid ALIAS FOR $1;
-  pLookAheadDays ALIAS FOR $2;
 
 BEGIN
 
-  RETURN ( ( SELECT itemsite_qtyonhand
+  RETURN ( ( SELECT qtyAvailable(itemsite_id)
              FROM itemsite
              WHERE (itemsite_id=pItemsiteid) ) +
            (SELECT qtyOrdered(pItemsiteid, pLookAheadDays)) -
            (SELECT qtyAllocated(pitemsiteid, pLookAheadDays)) );
 END;
-' LANGUAGE 'plpgsql' STABLE;
+$$ LANGUAGE plpgsql;
 
 
-CREATE OR REPLACE FUNCTION qtyAvailable(INTEGER, DATE) RETURNS NUMERIC AS '
+CREATE OR REPLACE FUNCTION qtyAvailable(pItemsiteid INTEGER,
+                                        pDate DATE) RETURNS NUMERIC STABLE AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemsiteid ALIAS FOR $1;
-  pDate ALIAS FOR $2;
 
 BEGIN
 
-  RETURN ( ( SELECT itemsite_qtyonhand
+  RETURN ( ( SELECT qtyAvailable(itemsite_id)
              FROM itemsite
              WHERE (itemsite_id=pItemsiteid) ) +
            (SELECT qtyOrdered(pItemsiteid, (pDate - CURRENT_DATE))) -
            (SELECT qtyAllocated(pItemsiteid, (pDate - CURRENT_DATE))) );
 END;
-' LANGUAGE 'plpgsql' STABLE;
+$$ LANGUAGE plpgsql;
 
diff --git a/foundation-database/public/functions/qtynetable.sql b/foundation-database/public/functions/qtynetable.sql
new file mode 100644 (file)
index 0000000..cb2a6fb
--- /dev/null
@@ -0,0 +1,44 @@
+
+CREATE OR REPLACE FUNCTION qtyNetable(pItemsiteId INTEGER) RETURNS NUMERIC STABLE AS $$
+-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _qty         NUMERIC = 0.0;
+
+BEGIN
+  _qty := qtyNetable(pItemsiteId, TRUE);
+
+  RETURN _qty;
+
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION qtyNetable(pItemsiteId INTEGER,
+                                      pNetable BOOLEAN) RETURNS NUMERIC STABLE AS $$
+-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _qty         NUMERIC = 0.0;
+
+BEGIN
+  IF (pNetable) THEN
+    -- Summarize itemloc qty for this itemsite/netable locations
+    -- or use itemsite_qtyonhand for regular/non-lot
+    SELECT COALESCE(SUM(itemloc_qty), itemsite_qtyonhand) INTO _qty
+      FROM itemsite LEFT OUTER JOIN itemloc ON (itemloc_itemsite_id=itemsite_id)
+                    LEFT OUTER JOIN location ON (location_id=itemloc_location_id)
+     WHERE (itemsite_id=pItemsiteId)
+       AND ((location_id IS NULL) OR (COALESCE(location_netable, true)))
+     GROUP BY itemsite_qtyonhand;
+  ELSE
+    -- Summarize itemloc qty for this itemsite/non-netable locations
+    SELECT COALESCE(SUM(itemloc_qty), 0.0) INTO _qty
+      FROM itemloc JOIN location ON (location_id=itemloc_location_id)
+     WHERE (itemloc_itemsite_id=pItemsiteId)
+       AND (NOT COALESCE(location_netable, true));
+  END IF;
+
+  RETURN _qty;
+
+END;
+$$ LANGUAGE plpgsql;
index 29823d9..719091a 100644 (file)
@@ -4,18 +4,18 @@ CREATE OR REPLACE FUNCTION relocateInventory(INTEGER, INTEGER, INTEGER, NUMERIC,
 BEGIN
   RETURN relocateInventory($1, $2, $3, $4, $5, CURRENT_TIMESTAMP);
 END;
-$$ LANGUAGE 'plpgsql';
-
-CREATE OR REPLACE FUNCTION relocateInventory(INTEGER, INTEGER, INTEGER, NUMERIC, TEXT, TIMESTAMP WITH TIME ZONE) RETURNS INTEGER AS $$
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION relocateInventory(pSourceItemlocid INTEGER,
+                                             pTargetLocationid INTEGER,
+                                             pItemsiteid INTEGER,
+                                             pQty NUMERIC,
+                                             pComments TEXT,
+                                             pGLDistTS TIMESTAMP WITH TIME ZONE) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pSourceItemlocid      ALIAS FOR $1;
-  pTargetLocationid     ALIAS FOR $2;
-  pItemsiteid           ALIAS FOR $3;
-  pQty                  ALIAS FOR $4;
-  pComments             ALIAS FOR $5;
-  _GlDistTS             TIMESTAMP WITH TIME ZONE := $6;
+  _GlDistTS             TIMESTAMP WITH TIME ZONE;
   _targetItemlocid      INTEGER;
   _invhistid            INTEGER;
   _p                    RECORD;
@@ -28,8 +28,10 @@ DECLARE
 
 BEGIN
 
-    IF ((_GlDistTS IS NULL) OR (CAST(_GlDistTS AS date)=CURRENT_DATE)) THEN
+    IF ((pGlDistTS IS NULL) OR (CAST(pGlDistTS AS date)=CURRENT_DATE)) THEN
       _GlDistTS := CURRENT_TIMESTAMP;
+    ELSE
+      _GLDistTS := pGLDistTS;
     END IF;
 
 --  Make sure the passed itemsite points to a real item
@@ -45,13 +47,9 @@ BEGIN
          itemloc_itemsite_id AS itemsiteid,
          itemloc_expiration,
          itemloc_warrpurc,
-         itemloc_qty,
-         sourceloc.location_netable AS sourcenet,
-         targetloc.location_netable AS targetnet INTO _p
-  FROM itemloc, location AS sourceloc, location AS targetloc
-  WHERE ( (itemloc_location_id=sourceloc.location_id)
-   AND (targetloc.location_id=pTargetLocationid)
-   AND (itemloc_id=pSourceItemlocid) );
+         itemloc_qty INTO _p
+  FROM itemloc
+  WHERE (itemloc_id=pSourceItemlocid);
 
 --  Check to make sure the qty being transfered exists
   IF (_p.itemloc_qty < pQty) THEN
@@ -141,42 +139,6 @@ BEGIN
   SET invhist_hasdetail=TRUE
   WHERE (invhist_id=_invhistid);
 
---  Post in incomming or outgoing NN transaction if required
-  IF (_p.sourcenet <> _p.targetnet) THEN
-    IF (_p.targetnet) THEN
-      _qty = (pQty * -1);
-    ELSE
-      _qty = pQty;
-    END IF;
-
-    INSERT INTO invhist
-    ( invhist_itemsite_id,
-      invhist_transtype, invhist_invqty,
-      invhist_qoh_before, invhist_qoh_after,
-      invhist_docnumber, invhist_comments, invhist_transdate,
-      invhist_invuom, invhist_unitcost, invhist_costmethod,
-      invhist_value_before, invhist_value_after, invhist_series) 
-    SELECT itemsite_id,
-           'NN', (_qty * -1),
-           itemsite_qtyonhand, (itemsite_qtyonhand - _qty),
-           '', '', _GlDistTS,
-           uom_name,
-           CASE WHEN (itemsite_costmethod='A') THEN avgcost(itemsite_id)
-                ELSE stdCost(item_id)
-           END, itemsite_costmethod,
-           itemsite_value, itemsite_value, _itemlocSeries
-    FROM item, itemsite, uom
-    WHERE ( (itemsite_item_id=item_id)
-     ANd (item_inv_uom_id=uom_id)
-     AND (itemsite_controlmethod <> 'N')
-     AND (itemsite_id=_p.itemsiteid) );
-
-    UPDATE itemsite
-    SET itemsite_qtyonhand = (itemsite_qtyonhand - _qty),
-        itemsite_nnqoh = (itemsite_nnqoh + _qty)
-    WHERE (itemsite_id=_p.itemsiteid);
-  END IF;
-
 --  Check to see if there is anything left at the target Itemloc and delete if not
 --  Could be zero if relocate increased a negative quantity to zero
   DELETE FROM itemloc
@@ -237,4 +199,4 @@ BEGIN
   RETURN _invhistid;
 
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index 5bf833a..14280db 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
                      noNeg(coitem_qtyord - coitem_qtyshipped +
                            coitem_qtyreturned - qtyAtShipping(pordertype, coitem_id)
                           ))) - coitem_qtyreserved) * coitem_qty_invuomratio
-                     ) <= itemsite_qtyonhand)
+                     ) <= qtyAvailable(itemsite_id))
               AND 
              (((COALESCE(pqty, roundQty(item_fractional,
                      noNeg(coitem_qtyord - coitem_qtyshipped +
@@ -57,7 +57,7 @@ BEGIN
                                      coitem_qtyreturned - qtyAtShipping(pordertype, coitem_id) - coitem_qtyreserved
                                      ) * coitem_qty_invuomratio
                      )
-              ) <= itemsite_qtyonhand)
+              ) <= qtyAvailable(itemsite_id))
         INTO _isqtyavail
         FROM coitem, itemsite, item
        WHERE ((coitem_itemsite_id=itemsite_id) 
@@ -72,7 +72,7 @@ BEGIN
                                    qtyAtShipping(pordertype, toitem_id)
                                    )
                    )
-           ) <= itemsite_qtyonhand) INTO _isqtyavail  
+           ) <= qtyAvailable(itemsite_id)) INTO _isqtyavail  
       FROM toitem, tohead, itemsite, item
      WHERE ((toitem_tohead_id=tohead_id)
        AND  (tohead_src_warehous_id=itemsite_warehous_id) 
index 54d85bc..ff36aba 100644 (file)
@@ -1,11 +1,8 @@
-CREATE OR REPLACE FUNCTION thawItemSite(INTEGER) RETURNS INTEGER AS $$
+CREATE OR REPLACE FUNCTION thawItemSite(pItemsiteid INTEGER) RETURNS INTEGER AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-  pItemsiteid ALIAS FOR $1;
   _qoh            NUMERIC := 0;
-  _netable_qoh    NUMERIC := 0;
-  _nonnetable_qoh NUMERIC := 0;
   _value          NUMERIC := 0;
   _itemlocid INTEGER;
   _itemloc RECORD;
@@ -48,9 +45,9 @@ BEGIN
 
 --  Cache the initial qty of the itemloc specified by the
 --  itemsite/location/lot/serial
-        SELECT itemloc_id, itemloc_qty, COALESCE(location_netable, TRUE) AS location_netable
+        SELECT itemloc_id, itemloc_qty
         INTO _itemloc
-        FROM itemloc LEFT OUTER JOIN location ON (location_id=itemloc_location_id)
+        FROM itemloc
         WHERE ( (itemloc_itemsite_id=pItemsiteid)
          AND (itemloc_location_id=_coarse.invdetail_location_id)
          AND (COALESCE(itemloc_ls_id,-1)=COALESCE(_coarse.invdetail_ls_id,-1))
@@ -70,17 +67,10 @@ BEGIN
             0, endOfTime() );
 
         _qoh := 0.0;
-        _netable_qoh := 0.0;
-        _nonnetable_qoh := 0.0;
 
         ELSE
           _itemlocid := _itemloc.itemloc_id;
           _qoh := _itemloc.itemloc_qty;
-          IF (_itemloc.location_netable) THEN
-            _netable_qoh := _itemloc.itemloc_qty;
-          ELSE
-            _nonnetable_qoh := _itemloc.itemloc_qty;
-          END IF;
         END IF;
 
 --  Now step through each unposted invdetail record for a given
@@ -104,11 +94,6 @@ BEGIN
 
 --  Update the running qoh
           _qoh = (_qoh + _fine.invdetail_qty);
-          IF (_itemloc.location_netable) THEN
-            _netable_qoh := (_netable_qoh + _fine.invdetail_qty);
-          ELSE
-            _nonnetable_qoh := (_nonnetable_qoh + _fine.invdetail_qty);
-          END IF;
 
         END LOOP;
 
@@ -166,11 +151,8 @@ BEGIN
 
     END LOOP;
 
--- _qoh can be used for the netable qoh because of the negative NN transactions
--- change to update qtyonhand with _netable_qoh
     UPDATE itemsite
-       SET itemsite_qtyonhand = _netable_qoh,
-           itemsite_nnqoh = _nonnetable_qoh,
+       SET itemsite_qtyonhand = _qoh,
            itemsite_value = CASE WHEN ((itemsite_costmethod='A') AND (_value < 0.0)) THEN 0.0
                                  ELSE _value END
      WHERE(itemsite_id=pItemsiteid);
@@ -180,4 +162,4 @@ BEGIN
   RETURN pItemsiteid;
 
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index 1beee66..4eff4ea 100644 (file)
@@ -1,12 +1,11 @@
-CREATE OR REPLACE FUNCTION updateStdCost(INTEGER, NUMERIC, NUMERIC, TEXT, TEXT) RETURNS BOOLEAN AS $$
+CREATE OR REPLACE FUNCTION updateStdCost(pItemcostid INTEGER,
+                                         pNewcost NUMERIC,
+                                         pOldcost NUMERIC,
+                                         pDocNumber TEXT,
+                                         pNotes TEXT) RETURNS BOOLEAN AS $$
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. 
 -- See www.xtuple.com/CPAL for the full text of the software license.
 DECLARE
-    pItemcostid        ALIAS FOR $1;
-    pNewcost   ALIAS FOR $2;
-    pOldcost   ALIAS FOR $3;
-    pDocNumber ALIAS FOR $4;
-    pNotes     ALIAS FOR $5;
     _itemcostid        INTEGER;
     _r         RECORD;
     _newcost   NUMERIC;
@@ -32,14 +31,14 @@ BEGIN
   END IF;
 
 --  Distribute to G/L, debit Inventory Asset, credit Inventory Cost Variance
-  FOR _r IN SELECT itemsite_id, (itemsite_qtyonhand + itemsite_nnqoh) AS totalQty,
+  FOR _r IN SELECT itemsite_id, itemsite_qtyonhand AS totalQty,
                    costcat_invcost_accnt_id, costcat_asset_accnt_id,
                    itemsite_costmethod
             FROM itemcost, itemsite, costcat
             WHERE ( (itemsite_item_id=itemcost_item_id)
              AND (itemsite_costcat_id=costcat_id)
              AND (itemsite_costmethod != 'A')
-             AND ((itemsite_qtyonhand + itemsite_nnqoh) <> 0)
+             AND (itemsite_qtyonhand <> 0.0)
              AND (itemcost_id=pItemcostid) ) LOOP
 --    IF (_newcost <> _oldcost) THEN
 --      RAISE NOTICE 'itemcost_id = %, Qty = %, Old Cost = %, New Cost = %', pItemcostid, _r.totalQty, _oldcost, _newcost;
@@ -153,4 +152,4 @@ BEGIN
 
     RETURN -1;
 END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
index b62f972..52bfd39 100644 (file)
@@ -46,7 +46,7 @@ BEGIN
                 item_descrip1, 
                 item_descrip2, 
                 uom_name,
-                noNeg(itemsite_qtyonhand) AS qoh, 
+                noNeg(qtyAvailable(itemsite_id)) AS qoh, 
                 noNeg(wo_qtyord - wo_qtyrcv) AS wobalance, 
                 qtyAllocated(itemsite_id, wo_duedate) AS allocated, 
                 qtyOrdered(itemsite_id, wo_duedate) AS ordered,                        
@@ -113,7 +113,7 @@ BEGIN
                         item_descrip1, 
                         item_descrip2, 
                         uom_name,                         
-                        noNeg(itemsite_qtyonhand) AS qoh, 
+                        noNeg(qtyAvailable(itemsite_id)) AS qoh, 
                         noNeg(itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyreq - womatl_qtyiss)) AS wobalance, 
                         qtyAllocated(itemsite_id, womatl_duedate) AS allocated, 
                         qtyOrdered(itemsite_id, womatl_duedate) AS ordered,                        
@@ -202,7 +202,7 @@ BEGIN
                 item_descrip1, 
                 item_descrip2, 
                 uom_name,
-                noNeg(itemsite_qtyonhand) AS qoh, 
+                noNeg(qtyAvailable(itemsite_id)) AS qoh, 
                 noNeg(wo_qtyord - wo_qtyrcv) AS wobalance, 
                 qtyAllocated(itemsite_id, wo_duedate) AS allocated, 
                 qtyOrdered(itemsite_id, wo_duedate) AS ordered,                        
index b2691c0..3ede5e4 100644 (file)
@@ -41,7 +41,7 @@ BEGIN
                 item_descrip1, 
                 item_descrip2, 
                 uom_name,
-                noNeg(itemsite_qtyonhand) AS qoh, 
+                noNeg(qtyAvailable(itemsite_id)) AS qoh, 
                 noNeg(itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyreq - womatl_qtyiss)) AS wobalance, 
                 qtyAllocated(itemsite_id, womatl_duedate) AS allocated, 
                 qtyOrdered(itemsite_id, womatl_duedate) AS ordered,
diff --git a/foundation-database/public/tables/bankrecimport.sql b/foundation-database/public/tables/bankrecimport.sql
new file mode 100644 (file)
index 0000000..de1fc7c
--- /dev/null
@@ -0,0 +1,9 @@
+select xt.create_table('bankrecimport', 'public');
+select xt.add_column('bankrecimport','bankrecimport_id', 'SERIAL', 'PRIMARY KEY', 'public');
+select xt.add_column('bankrecimport','bankrecimport_reference', 'TEXT', 'NOT NULL', 'public');
+select xt.add_column('bankrecimport','bankrecimport_descrip', 'TEXT', 'NOT NULL', 'public');
+select xt.add_column('bankrecimport','bankrecimport_comment', 'TEXT', 'NOT NULL', 'public');
+select xt.add_column('bankrecimport','bankrecimport_debit_amount', 'NUMERIC', 'NOT NULL', 'public');
+select xt.add_column('bankrecimport','bankrecimport_credit_amount', 'NUMERIC', 'NOT NULL', 'public');
+select xt.add_column('bankrecimport','bankrecimport_effdate', 'DATE', 'NOT NULL', 'public');
+select xt.add_column('bankrecimport','bankrecimport_curr_rate', 'NUMERIC', 'NOT NULL', 'public');
diff --git a/foundation-database/public/tables/bankrecimport.xml b/foundation-database/public/tables/bankrecimport.xml
new file mode 100644 (file)
index 0000000..f351c7c
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE openCSVAtlasDef>
+<CSVAtlas>
+ <CSVMap>
+  <Name>bankrec</Name>
+  <Table>public.bankrecimport</Table>
+  <Action>Insert</Action>
+  <PreSQL>DELETE FROM bankrecimport;</PreSQL>
+  <PostSQL>SELECT importBankrecCleared(-1);</PostSQL>
+  <CSVMapField>
+   <Name>bankrecimport_reference</Name>
+   <Type>QString</Type>
+   <Column>8</Column>
+  </CSVMapField>
+  <CSVMapField>
+   <Name>bankrecimport_descrip</Name>
+   <Type>QString</Type>
+   <Column>4</Column>
+  </CSVMapField>
+  <CSVMapField>
+   <Name>bankrecimport_comment</Name>
+   <Type>QString</Type>
+   <Column>9</Column>
+  </CSVMapField>
+  <CSVMapField>
+   <Name>bankrecimport_debit_amount</Name>
+   <Type>double</Type>
+   <Column>5</Column>
+  </CSVMapField>
+  <CSVMapField>
+   <Name>bankrecimport_credit_amount</Name>
+   <Type>double</Type>
+   <Column>6</Column>
+  </CSVMapField>
+  <CSVMapField>
+   <Name>bankrecimport_effdate</Name>
+   <Type>QDate</Type>
+   <Column>1</Column>
+  </CSVMapField>
+ </CSVMap>
+</CSVAtlas>
diff --git a/foundation-database/public/tables/itemsite.sql b/foundation-database/public/tables/itemsite.sql
new file mode 100644 (file)
index 0000000..5c5f7c4
--- /dev/null
@@ -0,0 +1,8 @@
+-- incident 23507:change how qoh, qoh available, and qoh netable are determined
+do $$
+begin
+if fetchMetricText('ServerVersion') < '4.7.0' then
+  update itemsite set itemsite_qtyonhand=(itemsite_qtyonhand + itemsite_nnqoh);
+  alter table itemsite drop column itemsite_nnqoh cascade;
+end if;
+end$$;
\ No newline at end of file
index 5fc9557..a5cf13d 100644 (file)
@@ -8,3 +8,11 @@ select xt.add_column('location','location_formatname', 'TEXT', NULL, 'public');
 select xt.add_index('location', 'location_formatname','location_location_formatname_idx', 'btree', 'public');
 UPDATE location SET location_formatname=formatLocationName(location_id) WHERE location_formatname IS NULL;
 
+-- incident 23507:change how qoh, qoh available, and qoh netable are determined
+select xt.add_column('location','location_usable', 'BOOLEAN', NULL, 'public');
+do $$
+begin
+if fetchMetricText('ServerVersion') < '4.7.0' then
+  update location set location_usable=true;
+end if;
+end$$;
index 01e632f..69461dd 100644 (file)
@@ -1,8 +1,8 @@
 -- Group: apOpenItems
 -- Name:  selectedpayments
--- Notes:
--- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
--- See www.xtuple.com/CPAL for the full text of the software license.
+-- Notes: 
+--        Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
+--        See www.xtuple.com/CPAL for the full text of the software license.
 
 SELECT *,
        CASE WHEN (apopen_doctype='V') THEN <? value("voucher") ?>
@@ -48,9 +48,9 @@ UNION
 SELECT apopen_id, apselect_id,
        (bankaccnt_name || '-' || bankaccnt_descrip) AS f_bank,
        (vend_number || '-' || vend_name) AS f_vendor,
-       apopen_docnumber, apopen_ponumber, apselect_amount,
+       apopen_docnumber, apopen_ponumber, -apselect_amount,
        apopen_invcnumber, apopen_doctype,
-       currToBase(apselect_curr_id, apselect_amount, CURRENT_DATE) AS apselect_amount_base,
+       currToBase(apselect_curr_id, apselect_amount, CURRENT_DATE) * -1.0 AS apselect_amount_base,
        currToBase(apselect_curr_id, apselect_amount, CURRENT_DATE) * -1.0 AS apselect_running_base,
        currConcat(apselect_curr_id) AS currAbbr
 FROM apopen, apselect, vendinfo, bankaccnt
index de92dbb..fa18e8e 100644 (file)
@@ -1,8 +1,8 @@
 -- Group: apOpenItems
 -- Name:  selectpayments
--- Notes:
--- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
--- See www.xtuple.com/CPAL for the full text of the software license.
+-- Notes: 
+--        Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
+--        See www.xtuple.com/CPAL for the full text of the software license.
 
 SELECT *,
        CASE WHEN (apopen_doctype='V') THEN <? value("voucher") ?>
@@ -73,11 +73,11 @@ SELECT apopen_id, COALESCE(apselect_id, -1) AS apselectid,
        (vend_number || '-' || vend_name) AS vendor,
        apopen_doctype, apopen_docnumber, apopen_ponumber, apopen_invcnumber,
        apopen_duedate, apopen_terms_id, apopen_docdate, apopen_status,
-       (apopen_amount - apopen_paid - apCheckPending(apopen_id)) AS amount,
-       ((apopen_amount - apopen_paid - apCheckPending(apopen_id)) / apopen_curr_rate) AS base_amount,
+       (apopen_amount - apopen_paid - apCheckPending(apopen_id))  * -1.0 AS amount,
+       ((apopen_amount - apopen_paid - apCheckPending(apopen_id)) / apopen_curr_rate) * -1.0 AS base_amount,
        ((apopen_amount - apopen_paid - apCheckPending(apopen_id)) / apopen_curr_rate) * -1.0 AS running_amount,
-       COALESCE(apselect_amount, 0.0) AS selected,
-       (COALESCE(apselect_amount, 0.0) / apopen_curr_rate) AS base_selected,
+       COALESCE(apselect_amount, 0.0) * -1.0 AS selected,
+       (COALESCE(apselect_amount, 0.0) / apopen_curr_rate) * -1.0 AS base_selected,
        (COALESCE(apselect_amount, 0.0) / apopen_curr_rate) * -1.0 AS running_selected,
        COALESCE(apselect_discount,0.0) AS discount,
        (COALESCE(apselect_discount,0.0) / apopen_curr_rate)AS base_discount,
index 28a6f08..b8b5bf4 100644 (file)
@@ -31,18 +31,11 @@ SELECT   coitem_id AS id, coitem_cohead_id AS altId,
                      (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2) AS baseextpricebalance,
          round((coitem_qtyord * coitem_qty_invuomratio) *
                      (coitem_unitcost / coitem_price_invuomratio), 2) AS extcost,
-         (round((coitem_qtyord * coitem_qty_invuomratio) *
-                     (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2) -
-          round((coitem_qtyord * coitem_qty_invuomratio) *
-                     (coitem_unitcost / coitem_price_invuomratio), 2)) AS margin,
-         CASE WHEN (coitem_price > 0.0) THEN
-           (round((coitem_qtyord * coitem_qty_invuomratio) *
-                       (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2) -
-            round((coitem_qtyord * coitem_qty_invuomratio) *
-                       (coitem_unitcost / coitem_price_invuomratio), 2)) /
-            round((coitem_qtyord * coitem_qty_invuomratio) *
-                       (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2)
-              ELSE 0.0
+         CASE WHEN (coitem_price = 0.0) THEN 0.0
+              ELSE ROUND(coitem_qtyord * coitem_qty_invuomratio * (coitem_price - coitem_unitcost) / coitem_price_invuomratio,2)
+         END AS margin,
+         CASE WHEN (coitem_price = 0.0) THEN 0.0
+              ELSE ((coitem_price - coitem_unitcost) / coitem_price)
          END AS marginpercent,
          curr_abbr AS currAbbr,
 -- TODO - not needed, remove? (very slow)
index a930353..df6f597 100644 (file)
@@ -29,44 +29,29 @@ FROM (
              invcnt_tagdate AS tagdate,
              item_number, (item_descrip1 || item_descrip2) AS item_descrip, warehous_code,
             CASE WHEN (location_id IS NOT NULL) THEN
-               location_name
+               formatLocationName(location_id)
                ELSE <? value("all") ?> END AS loc_specific,
-             CASE WHEN (invcnt_location_id IS NOT NULL)
-               THEN (SELECT SUM(itemloc_qty)
-                     FROM itemloc JOIN location ON (location_id=itemloc_location_id)
-                     WHERE ((itemloc_itemsite_id=itemsite_id)
-                       AND  (itemloc_location_id=invcnt_location_id)
-                       AND  (location_netable)))
-               ELSE itemsite_qtyonhand
-             END AS qoh,
-             CASE WHEN (invcnt_location_id IS NOT NULL)
-               THEN (SELECT SUM(itemloc_qty)
-                     FROM itemloc JOIN location ON (location_id=itemloc_location_id)
-                     WHERE ((itemloc_itemsite_id=itemsite_id)
-                       AND  (itemloc_location_id=invcnt_location_id)
-                       AND  (NOT location_netable)))
-               ELSE itemsite_nnqoh
-             END AS nnqoh,
+             qtyAtLocation(invcnt_itemsite_id, invcnt_location_id) AS qoh,
       <? if exists("showSlips") ?>
              calcTotalSlipQty(invcnt_id) AS qohafter,
-             (calcTotalSlipQty(invcnt_id) - (itemsite_qtyonhand + itemsite_nnqoh)) AS variance,
+             (calcTotalSlipQty(invcnt_id) - qtyAtLocation(invcnt_itemsite_id, invcnt_location_id)) AS variance,
              CASE WHEN (calcTotalSlipQty(invcnt_id) IS NULL) THEN NULL
-                  WHEN (((itemsite_qtyonhand + itemsite_nnqoh) = 0) AND (calcTotalSlipQty(invcnt_id) > 0)) THEN 1
-                  WHEN (((itemsite_qtyonhand + itemsite_nnqoh) = 0) AND (calcTotalSlipQty(invcnt_id) < 0)) THEN -1
-                  WHEN (((itemsite_qtyonhand + itemsite_nnqoh) = 0) AND (calcTotalSlipQty(invcnt_id) = 0)) THEN 0
-               ELSE ((1 - (calcTotalSlipQty(invcnt_id) / (itemsite_qtyonhand + itemsite_nnqoh))) * -1)
+                  WHEN ((qtyAtLocation(invcnt_itemsite_id, invcnt_location_id) = 0) AND (calcTotalSlipQty(invcnt_id) > 0)) THEN 1
+                  WHEN ((qtyAtLocation(invcnt_itemsite_id, invcnt_location_id) = 0) AND (calcTotalSlipQty(invcnt_id) < 0)) THEN -1
+                  WHEN ((qtyAtLocation(invcnt_itemsite_id, invcnt_location_id) = 0) AND (calcTotalSlipQty(invcnt_id) = 0)) THEN 0
+               ELSE ((1 - (calcTotalSlipQty(invcnt_id) / qtyAtLocation(invcnt_itemsite_id, invcnt_location_id))) * -1)
              END AS varianceprcnt,
-             (itemCost(itemsite_id) * (calcTotalSlipQty(invcnt_id) - (itemsite_qtyonhand + itemsite_nnqoh))) AS variancecost,
+             (itemCost(itemsite_id) * (calcTotalSlipQty(invcnt_id) - qtyAtLocation(invcnt_itemsite_id, invcnt_location_id))) AS variancecost,
       <? else ?>
              COALESCE(invcnt_qoh_after, 0.0) AS qohafter,
-             (invcnt_qoh_after - (itemsite_qtyonhand + itemsite_nnqoh)) AS variance,
+             (invcnt_qoh_after - qtyAtLocation(invcnt_itemsite_id, invcnt_location_id)) AS variance,
              CASE WHEN (invcnt_qoh_after IS NULL) THEN NULL
-                  WHEN (((itemsite_qtyonhand + itemsite_nnqoh) = 0) AND (invcnt_qoh_after > 0)) THEN 1
-                  WHEN (((itemsite_qtyonhand + itemsite_nnqoh) = 0) AND (invcnt_qoh_after < 0)) THEN -1
-                  WHEN (((itemsite_qtyonhand + itemsite_nnqoh) = 0) AND (invcnt_qoh_after = 0)) THEN 0
-               ELSE ((1 - (invcnt_qoh_after / (itemsite_qtyonhand + itemsite_nnqoh))) * -1)
+                  WHEN ((qtyAtLocation(invcnt_itemsite_id, invcnt_location_id) = 0) AND (invcnt_qoh_after > 0)) THEN 1
+                  WHEN ((qtyAtLocation(invcnt_itemsite_id, invcnt_location_id) = 0) AND (invcnt_qoh_after < 0)) THEN -1
+                  WHEN ((qtyAtLocation(invcnt_itemsite_id, invcnt_location_id) = 0) AND (invcnt_qoh_after = 0)) THEN 0
+               ELSE ((1 - (invcnt_qoh_after / qtyAtLocation(invcnt_itemsite_id, invcnt_location_id))) * -1)
              END AS varianceprcnt,
-             (itemCost(itemsite_id) * (invcnt_qoh_after - (itemsite_qtyonhand + itemsite_nnqoh))) AS variancecost,
+             (itemCost(itemsite_id) * (invcnt_qoh_after - qtyAtLocation(invcnt_itemsite_id, invcnt_location_id))) AS variancecost,
       <? endif ?>
              item_number AS orderby,
              0 AS xtindentrole
@@ -101,7 +86,6 @@ FROM (
              '' AS warehous_code,
              '' AS loc_specific,
              NULL AS qoh,
-             NULL AS nnqoh,
              cntslip_qty AS qohafter,
              NULL AS variance, NULL AS varianceprcnt, 0 AS variancecost,
              item_number AS orderby,
index 7a95ea0..baa6a66 100644 (file)
 -- See www.xtuple.com/CPAL for the full text of the software license.
 
 SELECT id, type, locationname, defaultlocation,
-                       location_netable, lotserial, f_expiration, expired,
-                        qty, qtytagged, (qty + qtytagged) AS balance,
-                        'qty' AS qty_xtnumericrole,
-                        'qty' AS qtytagged_xtnumericrole,
-                        'qty' AS balance_xtnumericrole,
-                        CASE WHEN expired THEN 'error' END AS qtforegroundrole, 
-                        CASE WHEN expired THEN 'error' 
-                             WHEN defaultlocation AND expired = false THEN 'altemphasis' 
-                        ELSE null END AS defaultlocation_qtforegroundrole, 
-                        CASE WHEN expired THEN 'error' 
-                             WHEN qty > 0 AND expired = false THEN 'altemphasis' 
-                        ELSE null END AS qty_qtforegroundrole 
-                 FROM ( 
-                <? if exists("cNoIncludeLotSerial") ?>
-                SELECT location_id AS id, <? value("locationType") ?> AS type,
-                       formatLocationName(location_id) AS locationname,
-                       CASE WHEN (<? value("transtype") ?> = 'R' AND location_id=itemsite_recvlocation_id) THEN TRUE
-                            WHEN (<? value("transtype") ?> = 'I' AND location_id=itemsite_issuelocation_id) THEN TRUE
-                            WHEN (<? value("transtype") ?> = 'O' AND location_id=itemsite_location_id) THEN TRUE
-                             ELSE FALSE
-                        END AS defaultlocation,
-                       location_netable,
-                       TEXT('') AS lotserial,
-                       TEXT(<? value("na") ?>) AS f_expiration, FALSE AS expired,
-                       qtyLocation(location_id, NULL, NULL, NULL, itemsite_id, itemlocdist_order_type, itemlocdist_order_id, itemlocdist_id) AS qty,
-                       itemlocdistQty(location_id, itemlocdist_id) AS qtytagged 
-                FROM itemlocdist, location, itemsite 
-                WHERE ( (itemlocdist_itemsite_id=itemsite_id)
-                 AND (itemsite_loccntrl)
-                 AND (itemsite_warehous_id=location_warehous_id)
-                 AND (validLocation(location_id, itemsite_id))
-                 AND (itemlocdist_id=<? value("itemlocdist_id") ?>) ) 
-                <? elseif exists("cIncludeLotSerial") ?>
-                SELECT itemloc_id AS id, <? value("itemlocType") ?> AS type,
-                       COALESCE(formatLocationName(location_id),
-                                <? value("undefined") ?>) AS locationname,
-                       (location_id IS NOT NULL AND
-                        CASE WHEN (<? value("transtype") ?> = 'R' AND location_id=itemsite_recvlocation_id) THEN TRUE
-                             WHEN (<? value("transtype") ?> = 'I' AND location_id=itemsite_issuelocation_id) THEN TRUE
-                             WHEN (<? value("transtype") ?> = 'O' AND location_id=itemsite_location_id) THEN TRUE
-                              ELSE FALSE
-                         END) AS defaultlocation,
-                       COALESCE(location_netable, false) AS location_netable,
-                       ls_number AS lotserial,
-                       CASE WHEN (itemsite_perishable) THEN formatDate(itemloc_expiration)
-                            ELSE <? value("na") ?>
-                       END AS f_expiration,
-                       CASE WHEN (itemsite_perishable) THEN (itemloc_expiration < CURRENT_DATE)
-                            ELSE FALSE 
-                       END AS expired,
-                       qtyLocation(itemloc_location_id, itemloc_ls_id, itemloc_expiration, itemloc_warrpurc, itemsite_id, itemlocdist_order_type, itemlocdist_order_id, itemlocdist_id) AS qty,
-                       ( SELECT COALESCE(SUM(target.itemlocdist_qty), 0)
-                         FROM itemlocdist AS target
-                         WHERE ( (target.itemlocdist_source_type='I')
-                          AND (target.itemlocdist_source_id=itemloc_id)
-                          AND (target.itemlocdist_itemlocdist_id=source.itemlocdist_id)) ) AS qtytagged 
-                FROM itemlocdist AS source, itemsite, itemloc 
-                   LEFT OUTER JOIN location ON (itemloc_location_id=location_id) 
-                   LEFT OUTER JOIN ls ON (itemloc_ls_id=ls_id) 
-                WHERE ( (source.itemlocdist_itemsite_id=itemsite_id)
-                 AND (itemloc_itemsite_id=itemsite_id)
-                 AND (source.itemlocdist_id=<? value("itemlocdist_id") ?>) ) 
-                 UNION 
-                SELECT location_id AS id, <? value("locationType") ?> AS type,
-                       formatLocationName(location_id) AS locationname,
-                       CASE WHEN (<? value("transtype") ?> = 'R' AND location_id=itemsite_recvlocation_id) THEN TRUE
-                            WHEN (<? value("transtype") ?> = 'I' AND location_id=itemsite_issuelocation_id) THEN TRUE
-                            WHEN (<? value("transtype") ?> = 'O' AND location_id=itemsite_location_id) THEN TRUE
-                             ELSE FALSE
-                        END AS defaultlocation,
-                       location_netable,
-                       TEXT('') AS lotserial,
-                       TEXT(<? value("na") ?>) AS f_expiration, FALSE AS expired,
-                       qtyLocation(location_id, NULL, NULL, NULL, itemsite_id, itemlocdist_order_type, itemlocdist_order_id, itemlocdist_id) AS qty,
-                       itemlocdistQty(location_id, itemlocdist_id) AS qtytagged 
-                FROM itemlocdist, location, itemsite 
-                WHERE ( (itemlocdist_itemsite_id=itemsite_id)
-                 AND (itemsite_loccntrl)
-                 AND (itemsite_warehous_id=location_warehous_id)
-                 AND (validLocation(location_id, itemsite_id))
-                  AND (itemsite_id=<? value("itemsite_id") ?> ) 
-                 AND (location_id NOT IN (SELECT DISTINCT itemloc_location_id FROM itemloc WHERE (itemloc_itemsite_id=itemsite_id)))
-                 AND (itemlocdist_id=<? value("itemlocdist_id") ?>) ) 
-                <? endif ?>
-                ) AS data 
-                 WHERE ((TRUE) 
-                <? if exists("showOnlyTagged") ?>
-                AND (qtytagged != 0) 
-                <? endif ?>
-                 <? if exists("showQtyOnly") ?>
-                 AND (qty > 0) 
-                 <? endif ?>
-                ) ORDER BY locationname;
+           location_netable, location_usable, lotserial, f_expiration, expired,
+           qty, qtytagged, (qty + qtytagged) AS balance,
+           'qty' AS qty_xtnumericrole,
+           'qty' AS qtytagged_xtnumericrole,
+           'qty' AS balance_xtnumericrole,
+           CASE WHEN expired THEN 'error' END AS qtforegroundrole, 
+           CASE WHEN defaultlocation AND expired = false THEN 'altemphasis' 
+                WHEN expired THEN 'error' 
+                ELSE null END AS defaultlocation_qtforegroundrole, 
+           CASE WHEN expired THEN 'error' 
+                WHEN qty > 0 AND expired = false THEN 'altemphasis' 
+                ELSE null END AS qty_qtforegroundrole 
+FROM ( 
+  <? if exists("cNoIncludeLotSerial") ?>
+    SELECT location_id AS id, <? value("locationType") ?> AS type,
+           formatLocationName(location_id) AS locationname,
+           CASE WHEN (<? value("transtype") ?> = 'R' AND location_id=itemsite_recvlocation_id) THEN TRUE
+                WHEN (<? value("transtype") ?> = 'I' AND location_id=itemsite_issuelocation_id) THEN TRUE
+                WHEN (<? value("transtype") ?> = 'O' AND location_id=itemsite_location_id) THEN TRUE
+                ELSE FALSE
+           END AS defaultlocation,
+           COALESCE(location_netable, true) AS location_netable,
+           COALESCE(location_usable, true) AS location_usable,
+           TEXT('') AS lotserial,
+           TEXT(<? value("na") ?>) AS f_expiration, FALSE AS expired,
+           qtyLocation(location_id, NULL, NULL, NULL,
+                       itemsite_id, itemlocdist_order_type, itemlocdist_order_id, itemlocdist_id) AS qty,
+           itemlocdistQty(location_id, itemlocdist_id) AS qtytagged 
+    FROM itemlocdist, location, itemsite 
+    WHERE ( (itemlocdist_itemsite_id=itemsite_id)
+      AND (itemsite_loccntrl)
+      AND (itemsite_warehous_id=location_warehous_id)
+      AND (validLocation(location_id, itemsite_id))
+      AND (itemlocdist_id=<? value("itemlocdist_id") ?>) ) 
+  <? elseif exists("cIncludeLotSerial") ?>
+    SELECT itemloc_id AS id, <? value("itemlocType") ?> AS type,
+           COALESCE(formatLocationName(location_id),
+           <? value("undefined") ?>) AS locationname,
+           (location_id IS NOT NULL AND
+             CASE WHEN (<? value("transtype") ?> = 'R' AND location_id=itemsite_recvlocation_id) THEN TRUE
+                  WHEN (<? value("transtype") ?> = 'I' AND location_id=itemsite_issuelocation_id) THEN TRUE
+                  WHEN (<? value("transtype") ?> = 'O' AND location_id=itemsite_location_id) THEN TRUE
+                  ELSE FALSE
+             END) AS defaultlocation,
+           COALESCE(location_netable, true) AS location_netable,
+           COALESCE(location_usable, true) AS location_usable,
+           ls_number AS lotserial,
+           CASE WHEN (itemsite_perishable) THEN formatDate(itemloc_expiration)
+                ELSE <? value("na") ?>
+           END AS f_expiration,
+           CASE WHEN (itemsite_perishable) THEN (itemloc_expiration < CURRENT_DATE)
+                ELSE FALSE 
+           END AS expired,
+           qtyLocation(itemloc_location_id, itemloc_ls_id, itemloc_expiration,
+                       itemloc_warrpurc, itemsite_id, itemlocdist_order_type,
+                       itemlocdist_order_id, itemlocdist_id) AS qty,
+           ( SELECT COALESCE(SUM(target.itemlocdist_qty), 0)
+             FROM itemlocdist AS target
+             WHERE ( (target.itemlocdist_source_type='I')
+               AND (target.itemlocdist_source_id=itemloc_id)
+               AND (target.itemlocdist_itemlocdist_id=source.itemlocdist_id)) ) AS qtytagged 
+    FROM itemlocdist AS source, itemsite, itemloc 
+         LEFT OUTER JOIN location ON (itemloc_location_id=location_id) 
+         LEFT OUTER JOIN ls ON (itemloc_ls_id=ls_id) 
+   WHERE ( (source.itemlocdist_itemsite_id=itemsite_id)
+     AND (itemloc_itemsite_id=itemsite_id)
+     AND (source.itemlocdist_id=<? value("itemlocdist_id") ?>) ) 
+    UNION 
+    SELECT location_id AS id, <? value("locationType") ?> AS type,
+           formatLocationName(location_id) AS locationname,
+           CASE WHEN (<? value("transtype") ?> = 'R' AND location_id=itemsite_recvlocation_id) THEN TRUE
+                WHEN (<? value("transtype") ?> = 'I' AND location_id=itemsite_issuelocation_id) THEN TRUE
+                WHEN (<? value("transtype") ?> = 'O' AND location_id=itemsite_location_id) THEN TRUE
+                ELSE FALSE
+           END AS defaultlocation,
+           COALESCE(location_netable, true) AS location_netable,
+           COALESCE(location_usable, true) AS location_usable,
+           TEXT('') AS lotserial,
+           TEXT(<? value("na") ?>) AS f_expiration, FALSE AS expired,
+           qtyLocation(location_id, NULL, NULL, NULL,
+                       itemsite_id, itemlocdist_order_type, itemlocdist_order_id, itemlocdist_id) AS qty,
+           itemlocdistQty(location_id, itemlocdist_id) AS qtytagged 
+    FROM itemlocdist, location, itemsite 
+    WHERE ( (itemlocdist_itemsite_id=itemsite_id)
+      AND (itemsite_loccntrl)
+      AND (itemsite_warehous_id=location_warehous_id)
+      AND (validLocation(location_id, itemsite_id))
+      AND (itemsite_id=<? value("itemsite_id") ?> ) 
+      AND (location_id NOT IN (SELECT DISTINCT itemloc_location_id
+                               FROM itemloc
+                               WHERE (itemloc_itemsite_id=itemsite_id)))
+      AND (itemlocdist_id=<? value("itemlocdist_id") ?>) ) 
+  <? endif ?>
+  ) AS data 
+WHERE ((TRUE) 
+   AND ( (<? value("transtype") ?> != 'I') OR (<? value("transtype") ?> = 'I' AND location_usable) )
+<? if exists("showOnlyTagged") ?>
+  AND (qtytagged != 0) 
+<? endif ?>
+<? if exists("showQtyOnly") ?>
+  AND (qty > 0) 
+<? endif ?>
+) ORDER BY locationname;
index 2eee3c9..6996987 100644 (file)
@@ -94,10 +94,10 @@ FROM (
       GROUP BY cohead_id, item_number, cust_number,
                cust_name, cohead_orderdate, pack_id, coitem_scheddate
   <? if exists("onlyShowShortages") ?>
-      HAVING (MIN(noNeg(itemsite_qtyonhand) +
+      HAVING (MIN(noNeg(qtyAvailable(itemsite_id)) +
                   qtyOrdered(itemsite_id, coitem_scheddate) -
                   qtyAllocated(itemsite_id, coitem_scheddate)) < 0
-              OR MIN(noNeg(itemsite_qtyonhand) +
+              OR MIN(noNeg(qtyAvailable(itemsite_id)) +
                   qtyOrdered(itemsite_id, coitem_scheddate) -
                   noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned)) < 0
            )
@@ -108,7 +108,7 @@ FROM (
             item_number,
             item_number AS trueitem_number,
             (item_descrip1 || ' ' || item_descrip2) AS descrip,
-            uom_name, noNeg(itemsite_qtyonhand) AS qoh,
+            uom_name, noNeg(qtyAvailable(itemsite_id)) AS qoh,
             noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) AS sobalance,
             qtyAllocated(itemsite_id, coitem_scheddate) AS allocated,
             qtyOrdered(itemsite_id, coitem_scheddate) AS ordered,
@@ -138,8 +138,8 @@ FROM (
                                   WHERE(custtype_code ~ <? value("custtype_pattern") ?>)))
 <? endif ?>
 <? if exists("onlyShowShortages") ?>
-        AND ((noNeg(itemsite_qtyonhand) + qtyOrdered(itemsite_id, coitem_scheddate) - qtyAllocated(itemsite_id, coitem_scheddate) < 0)
-          OR (noNeg(itemsite_qtyonhand) + qtyOrdered(itemsite_id, coitem_scheddate) - noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) < 0))
+        AND ((noNeg(qtyAvailable(itemsite_id)) + qtyOrdered(itemsite_id, coitem_scheddate) - qtyAllocated(itemsite_id, coitem_scheddate) < 0)
+          OR (noNeg(qtyAvailable(itemsite_id)) + qtyOrdered(itemsite_id, coitem_scheddate) - noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) < 0))
 <? endif ?>
     )
 <? if exists("showWoSupply") ?>
@@ -167,7 +167,7 @@ FROM (
            AND (wo_status IN ('E','R','I'))
            AND (wo_qtyord-wo_qtyrcv > 0)
            AND (noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned-qtyatshipping(coitem_id)) >
-            (SELECT itemsite_qtyonhand FROM itemsite WHERE (itemsite_id=coitem_itemsite_id))))
+            (SELECT qtyAvailable(itemsite_id) FROM itemsite WHERE (itemsite_id=coitem_itemsite_id))))
      WHERE ((coitem_cohead_id=cohead_id)
         AND (coitem_itemsite_id=itemsite_id)
         AND (itemsite_warehous_id=warehous_id)
@@ -184,8 +184,8 @@ FROM (
                                   WHERE(custtype_code ~ <? value("custtype_pattern") ?>)))
   <? endif ?>
   <? if exists("onlyShowShortages") ?>
-        AND ((noNeg(itemsite_qtyonhand) + qtyOrdered(itemsite_id, coitem_scheddate) - qtyAllocated(itemsite_id, coitem_scheddate) < 0)
-          OR (noNeg(itemsite_qtyonhand) + qtyOrdered(itemsite_id, coitem_scheddate) - noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) < 0))
+        AND ((noNeg(qtyAvailable(itemsite_id)) + qtyOrdered(itemsite_id, coitem_scheddate) - qtyAllocated(itemsite_id, coitem_scheddate) < 0)
+          OR (noNeg(qtyAvailable(itemsite_id)) + qtyOrdered(itemsite_id, coitem_scheddate) - noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) < 0))
   <? endif ?>
   )
 <? endif ?>
index ddeabd6..53ab1ce 100644 (file)
@@ -37,7 +37,7 @@ FROM (SELECT
              END AS altId,
              item_number, item_descrip1, item_descrip2, item_inv_uom_id,
              warehous_id, warehous_code, itemsite_leadtime,
-             itemsite_qtyonhand AS qoh,
+             qtyAvailable(itemsite_id) AS qoh,
              CASE WHEN itemsite_useparams THEN itemsite_reorderlevel
                   ELSE 0.0
              END AS reorderlevel,
index b607ba4..cfc41cd 100644 (file)
@@ -8,6 +8,7 @@
 SELECT *,
        <? value("na") ?> AS locationname_xtnullrole,
        <? value("na") ?> AS netable_xtnullrole,
+       <? value("na") ?> AS usable_xtnullrole,
        <? value("na") ?> AS lotserial_xtnullrole,
        <? value("na") ?> AS expiration_xtnullrole,
        <? value("na") ?> AS warranty_xtnullrole,
@@ -25,6 +26,8 @@ FROM (SELECT itemloc_id, 1 AS type, warehous_code,
              END AS locationname,
              CASE WHEN (location_id IS NOT NULL) THEN location_netable
              END AS netable,
+             CASE WHEN (location_id IS NOT NULL) THEN location_usable
+             END AS usable,
              CASE WHEN (itemsite_controlmethod IN ('L', 'S')) THEN
                         formatlotserialnumber(itemloc_ls_id)
              END AS lotserial,
@@ -88,6 +91,7 @@ FROM (SELECT itemloc_id, 1 AS type, warehous_code,
              itemsite_warrpurc, NULL AS itemloc_warrpurc,
              NULL AS locationname,
              NULL AS netable,
+             NULL AS usable,
              NULL AS lotserial,
              NULL AS expiration,
              NULL AS warranty,
index c4389b9..454227f 100644 (file)
@@ -4,8 +4,8 @@
 -- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
 -- See www.xtuple.com/CPAL for the full text of the software license.
 
-SELECT formatQty(itemsite_qtyonhand) AS f_qoh,itemsite_qtyonhand
-       qtyAllocated(itemsite_id, findPeriodStart(<? value("cursorId") ?>),
+SELECT qtyNetable(itemsite_id) AS qoh, formatQty(qtyNetable(itemsite_id)) AS f_qoh,
+       qtyAllocated(itemsite_id, findPeriodStart(<? value("cursorId") ?>),
                        findPeriodEnd(<? value("cursorId") ?>)) AS allocations<? value("counter") ?>,
        qtyOrdered(itemsite_id, findPeriodStart(<? value("cursorId") ?>),
                        findPeriodEnd(<? value("cursorId") ?>)) AS orders<? value("counter") ?>,
index c68cc92..ec14474 100644 (file)
@@ -38,7 +38,7 @@ SELECT itemsite_id, reorderlevel,
                 ib.*,
                 ((bomdata_qtyreq::NUMERIC * <? value("buildQty") ?>) * (1 + bomdata_scrap::NUMERIC)) AS pendalloc,
                 qtyAllocated(itemsite_id, DATE(<? value("buildDate") ?>)) AS totalalloc,
-                noNeg(itemsite_qtyonhand) AS qoh,
+                noNeg(qtyAvailable(itemsite_id)) AS qoh,
                 qtyOrdered(itemsite_id, DATE(<? value("buildDate") ?>)) AS ordered
            FROM indentedBOM(<? value("item_id") ?>,
                             getActiveRevId('BOM', <? value("item_id") ?>),
@@ -77,7 +77,7 @@ FROM ( SELECT itemsite_id, bomitem_seqnumber, item_number,
               ((itemuomtouom(bomitem_item_id, bomitem_uom_id, NULL,
                             (bomitem_qtyfxd + bomitem_qtyper * <? value("buildQty") ?>) * (1 + bomitem_scrap)))) AS pendalloc,
               qtyAllocated(itemsite_id, DATE(<? value("buildDate") ?>)) AS totalalloc,
-              noNeg(itemsite_qtyonhand) AS qoh,
+              noNeg(qtyAvailable(itemsite_id)) AS qoh,
               qtyOrdered(itemsite_id, DATE(<? value("buildDate") ?>)) AS ordered,
               CASE WHEN(itemsite_useparams) THEN itemsite_reorderlevel ELSE 0.0 END AS reorderlevel
        FROM itemsite, item, bomitem(<? value("item_id") ?>), uom
index 840c413..5ca4799 100644 (file)
@@ -5,6 +5,7 @@
 -- See www.xtuple.com/CPAL for the full text of the software license.
 
 SELECT pr_id, itemsite_id, itemsite_qtyonhand, itemsite_reorderlevel,
+       qtyNetable(itemsite_id) AS netableqoh, qtyNetable(itemsite_id, FALSE) AS nonnetableqoh,
        item_number, (item_descrip1 || ' ' || item_descrip2) AS description,
        pr.*,
        CASE WHEN (pr_order_type='W') THEN ('W/O ' || ( SELECT formatWoNumber(womatl_wo_id)
index cd80d69..8862e39 100644 (file)
@@ -159,10 +159,15 @@ SELECT itemsite_id, detail,warehous_code,
        defaultlocation,
        reorderlevel, formatQty(reorderlevel) AS f_reorderlevel,
        qoh, formatQty(qoh) AS f_qoh,
-       nnqoh, formatQty(nnqoh) AS f_nnqoh,
-       CASE WHEN (itemsite_loccntrl) THEN nnqoh END AS f_nnqoh,
+       availqoh, formatQty(availqoh) AS f_availqoh,
+       nonavailqoh, formatQty(nonavailqoh) AS f_nonavailqoh,
+       netqoh, formatQty(netqoh) AS f_netqoh,
+       nonnetqoh, formatQty(nonnetqoh) AS f_nonnetqoh,
        cost, (cost * qoh) AS value,
-       CASE WHEN (itemsite_loccntrl) THEN (cost * nnqoh) END AS nnvalue,
+       (cost * availqoh) AS availvalue,
+       (cost * nonavailqoh) AS nonavailvalue,
+       (cost * netqoh) AS netvalue,
+       (cost * nonnetqoh) AS nonnetvalue,
        CASE WHEN(itemsite_costmethod='A') THEN 'Average'
             WHEN(itemsite_costmethod='S') THEN 'Standard'
             WHEN(itemsite_costmethod='J') THEN 'Job'
@@ -171,7 +176,10 @@ SELECT itemsite_id, detail,warehous_code,
        END AS costmethod,
   <? if exists("showValue") ?>
        formatMoney(cost) AS f_cost, (cost * qoh) AS f_value,
-       CASE WHEN (itemsite_loccntrl) THEN (cost * nnqoh) END AS f_nnvalue,
+       formatMoney(cost * availqoh) AS f_availvalue,
+       formatMoney(cost * nonavailqoh) AS f_nonavailvalue,
+       formatMoney(cost * netqoh) AS f_netvalue,
+       formatMoney(cost * nonnetqoh) AS f_nonnetvalue,
        CASE WHEN(itemsite_costmethod='A') THEN 'Average'
             WHEN(itemsite_costmethod='S') THEN 'Standard'
             WHEN(itemsite_costmethod='J') THEN 'Job'
@@ -181,16 +189,34 @@ SELECT itemsite_id, detail,warehous_code,
   <? endif ?>
        'qty' AS reorderlevel_xtnumericrole,
        'qty' AS qoh_xtnumericrole,
-       'qty' AS f_nnqoh_xtnumericrole,
+       'qty' AS availqoh_xtnumericrole,
+       'qty' AS nonavailqoh_xtnumericrole,
+       'qty' AS netqoh_xtnumericrole,
+       'qty' AS nonnetqoh_xtnumericrole,
        0 AS qoh_xttotalrole,
-       0 AS nnqoh_xttotalrole,
+       0 AS availqoh_xttotalrole,
+       0 AS nonavailqoh_xttotalrole,
+       0 AS netqoh_xttotalrole,
+       0 AS nonnetqoh_xttotalrole,
        'cost' AS cost_xtnumericrole,
        'curr' AS value_xtnumericrole,
-       'curr' AS nnvalue_xtnumericrole,
+       'curr' AS availvalue_xtnumericrole,
+       'curr' AS nonavailvalue_xtnumericrole,
+       'curr' AS netvalue_xtnumericrole,
+       'curr' AS nonnetvalue_xtnumericrole,
        0 AS value_xttotalrole,
-       0 AS nnvalue_xttotalrole,
-       <? value("na") ?> AS nnqoh_xtnullrole,
-       <? value("na") ?> AS nnvalue_xtnullrole,
+       0 AS availvalue_xttotalrole,
+       0 AS nonavailvalue_xttotalrole,
+       0 AS netvalue_xttotalrole,
+       0 AS nonnetvalue_xttotalrole,
+       <? value("na") ?> AS availqoh_xtnullrole,
+       <? value("na") ?> AS nonavailqoh_xtnullrole,
+       <? value("na") ?> AS availvalue_xtnullrole,
+       <? value("na") ?> AS nonavailvalue_xtnullrole,
+       <? value("na") ?> AS netqoh_xtnullrole,
+       <? value("na") ?> AS nonnetqoh_xtnullrole,
+       <? value("na") ?> AS netvalue_xtnullrole,
+       <? value("na") ?> AS nonnetvalue_xtnullrole,
        CASE WHEN (qoh < 0) THEN 'error' END AS qoh_qtforegroundrole,
        CASE WHEN (reorderlevel > qoh) THEN 'warning' END AS qoh_qtforegroundrole
 FROM (
@@ -205,10 +231,16 @@ FROM (
              CASE WHEN(itemsite_useparams) THEN itemsite_reorderlevel ELSE 0.0 END AS reorderlevel,
   <? if exists("asOf") ?>
              COALESCE(invbal_qoh_ending,0) AS qoh,
-             COALESCE(invbal_nn_ending,0) AS nnqoh,
+             COALESCE(invbal_qoh_ending,0) AS availqoh,
+             COALESCE(invbal_nn_ending,0) AS nonavailqoh,
+             COALESCE(invbal_qoh_ending,0) AS netqoh,
+             COALESCE(invbal_nn_ending,0) AS nonnetqoh,
   <? else ?>
              itemsite_qtyonhand AS qoh,
-             itemsite_nnqoh AS nnqoh,
+             qtyAvailable(itemsite_id) AS availqoh,
+             qtyAvailable(itemsite_id, FALSE) AS nonavailqoh,
+             qtyNetable(itemsite_id) AS netqoh,
+             qtyNetable(itemsite_id, FALSE) AS nonnetqoh,
   <? endif ?>
   <? if exists("useStandardCosts") ?>
              stdcost(item_id) AS cost
@@ -219,8 +251,8 @@ FROM (
              COALESCE((invbal_value_ending / CASE WHEN(invbal_qoh_ending=0) THEN 1
                                                   ELSE invbal_qoh_ending END),0) AS cost
     <? else ?>
-             (itemsite_value / CASE WHEN((itemsite_qtyonhand + itemsite_nnqoh)=0) THEN 1
-                                    ELSE (itemsite_qtyonhand + itemsite_nnqoh) END) AS cost
+             (itemsite_value / CASE WHEN(itemsite_qtyonhand=0) THEN 1
+                                    ELSE itemsite_qtyonhand END) AS cost
     <? endif ?>
   <? endif ?>
       FROM item, whsinfo, classcode, uom, costcat, itemsite
index 7d0b90a..a4239d8 100644 (file)
@@ -7,7 +7,7 @@
 SELECT itemsite_id, itemtype, warehous_code, item_number,
        (item_descrip1 || ' ' || item_descrip2) AS itemdescrip,
        reorderdate, reorderlevel,
-       (itemsite_qtyonhand - qtyAllocated(itemsite_id, reorderdate) +
+       (qtyNetable(itemsite_id) - qtyAllocated(itemsite_id, reorderdate) +
          qtyOrdered(itemsite_id, reorderdate)) AS projavail,
        'qty' AS reorderlevel_xtnumericrole,
        'qty' AS projavail_xtnumericrole
@@ -22,9 +22,9 @@ FROM (SELECT itemsite_id,
                          <? value("lookAheadDays") ?>,
                          <? value("includePlannedOrders") ?>)
              AS reorderdate,
-             itemsite_qtyonhand, reorderlevel
+             reorderlevel
       FROM (SELECT itemsite_id, itemsite_item_id,
-                   itemsite_warehous_id, itemsite_qtyonhand,
+                   itemsite_warehous_id,
                    CASE WHEN(itemsite_useparams) THEN itemsite_reorderlevel
                      ELSE 0.0
                    END AS reorderlevel
index a5ccea5..c94d852 100644 (file)
@@ -6,7 +6,7 @@
 
 SELECT orderid, altorderid, ordertype, ordernumber, sequence, item_number,
        duedate, amount, qtyordered,  qtyreceived, balance,
-       balance AS runningavail,
+       balance AS runningavail, balance AS runningnetable,
 <? if exists("isReport") ?>
        CASE WHEN duedate = startOfTime() THEN ''
             ELSE formatDate(duedate) END AS f_duedate,
@@ -17,7 +17,9 @@ SELECT orderid, altorderid, ordertype, ordernumber, sequence, item_number,
 <? endif ?>
        notes,
        1 AS runningavail_xtrunningrole,
+       1 AS runningnetable_xtrunningrole,
        <? value("qoh") ?> AS runningavail_xtrunninginit,
+       <? value("netableqoh") ?> AS runningnetable_xtrunninginit,
        CASE WHEN late THEN 'error' END AS duedate_qtforegroundrole,
        CASE WHEN duedate = startOfTime() THEN '' END AS duedate_qtdisplayrole,
        CASE WHEN ordertype ~ <? value("plannedPo") ?> OR
index abd4a32..85a12f3 100644 (file)
@@ -59,8 +59,8 @@ SELECT coitem_id, coitem_altid, groupby,
             ELSE 1
        END AS xtindentrole,
        spplytype, ordrnumbr,
-       itemsite_qtyonhand,
-       'qty' AS itemsite_qtyonhand_xtnumericrole
+       availableqoh,
+       'qty' AS availableqoh_xtnumericrole
 <? if exists("includeReservations") ?>
        ,
        reserved,
@@ -123,11 +123,11 @@ SELECT coitem_id,
             WHEN coitem_order_type='R' THEN (pr_number || '-' || pr_subnumber)
             ELSE TEXT (' ')
        END AS ordrnumbr,
-       itemsite_qtyonhand
+       qtyAvailable(itemsite_id) AS availableqoh
 <? if exists("includeReservations") ?>
        ,
        coitem_qtyreserved AS reserved,
-       itemsite_qtyonhand - qtyreserved(itemsite_id) AS reservable
+       qtyAvailable(itemsite_id) - qtyReserved(itemsite_id) AS reservable
 <? endif?>
   FROM cohead
        JOIN coitem ON (coitem_cohead_id=cohead_id)
index 2096fa5..a92db1e 100644 (file)
@@ -5,9 +5,9 @@
 --        See www.xtuple.com/CPAL for the full text of the software license.
 
 SELECT s_itemsite_id, warehous_code, item_number, itemdescrip,
-       qtyonhand, reorderlevel, leadtime, itemsub_rank,
+       availableqoh, reorderlevel, leadtime, itemsub_rank,
        allocated, ordered, available,
-       'qty' AS qtyonhand_xtnumericrole,
+       'qty' AS availableqoh_xtnumericrole,
        'qty' AS allocated_xtnumericrole,
        'qty' AS ordered_xtnumericrole,
        'qty' AS reorderlevel_xtnumericrole,
@@ -17,14 +17,14 @@ FROM (SELECT sub.itemsite_id AS s_itemsite_id,
              warehous_code, item_number,
              (item_descrip1 || ' ' || item_descrip2) AS itemdescrip,
 <? if exists("normalize") ?>
-             (sub.itemsite_qtyonhand * itemsub_uomratio) AS qtyonhand,
+             (qtyAvailable(sub.itemsite_id) * itemsub_uomratio) AS availableqoh,
              (CASE WHEN(sub.itemsite_useparams)
                    THEN sub.itemsite_reorderlevel
                 ELSE 0.0
              END * itemsub_uomratio) AS reorderlevel,
              sub.itemsite_leadtime AS leadtime, itemsub_rank,
 <? else ?>
-             (sub.itemsite_qtyonhand) AS qtyonhand,
+             (qtyAvailable(sub.itemsite_id)) AS availableqoh,
              CASE WHEN(sub.itemsite_useparams) THEN sub.itemsite_reorderlevel
                ELSE 0.0
              END AS reorderlevel,
@@ -34,37 +34,37 @@ FROM (SELECT sub.itemsite_id AS s_itemsite_id,
   <? if exists("normalize") ?>
              (qtyAllocated(sub.itemsite_id, sub.itemsite_leadtime) * itemsub_uomratio) AS allocated,
              (qtyOrdered(sub.itemsite_id, sub.itemsite_leadtime) * itemsub_uomratio) AS ordered,
-             ((sub.itemsite_qtyonhand * itemsub_uomratio)
+             ((qtyAvailable(sub.itemsite_id) * itemsub_uomratio)
               + (qtyOrdered(sub.itemsite_id, sub.itemsite_leadtime) * itemsub_uomratio)
               - (qtyAllocated(sub.itemsite_id, sub.itemsite_leadtime) * itemsub_uomratio)) AS available
   <? else ?>
              (qtyAllocated(sub.itemsite_id, sub.itemsite_leadtime)) AS allocated,
              (qtyOrdered(sub.itemsite_id, sub.itemsite_leadtime)) AS ordered,
-             (sub.itemsite_qtyonhand + qtyOrdered(sub.itemsite_id, sub.itemsite_leadtime)
+             (qtyAvailable(sub.itemsite_id) + qtyOrdered(sub.itemsite_id, sub.itemsite_leadtime)
               - qtyAllocated(sub.itemsite_id, sub.itemsite_leadtime)) AS available
   <? endif ?>
 <? elseif exists("byDays") ?>
   <? if exists("normalize") ?>
              (qtyAllocated(sub.itemsite_id, <? value("days") ?>) * itemsub_uomratio) AS allocated,
              (qtyOrdered(sub.itemsite_id, <? value("days") ?>) * itemsub_uomratio) AS ordered,
-             ((sub.itemsite_qtyonhand * itemsub_uomratio) + (qtyOrdered(sub.itemsite_id, <? value("days") ?>) * itemsub_uomratio)
+             ((qtyAvailable(sub.itemsite_id) * itemsub_uomratio) + (qtyOrdered(sub.itemsite_id, <? value("days") ?>) * itemsub_uomratio)
               - (qtyAllocated(sub.itemsite_id, <? value("days") ?>) * itemsub_uomratio)) AS available
   <? else ?>
              (qtyAllocated(sub.itemsite_id, <? value("days") ?>)) AS allocated,
              (qtyOrdered(sub.itemsite_id, <? value("days") ?>)) AS ordered,
-             (sub.itemsite_qtyonhand + qtyOrdered(sub.itemsite_id, <? value("days") ?>)
+             (qtyAvailable(sub.itemsite_id) + qtyOrdered(sub.itemsite_id, <? value("days") ?>)
               - qtyAllocated(sub.itemsite_id, <? value("days") ?>)) AS available
   <? endif ?>
 <? elseif exists("byDate") ?>
   <? if exists("normalize") ?>
              (qtyAllocated(sub.itemsite_id, (<? value("date") ?> - CURRENT_DATE)) * itemsub_uomratio) AS allocated,
              (qtyOrdered(sub.itemsite_id, (<? value("date") ?> - CURRENT_DATE)) * itemsub_uomratio) AS ordered,
-             ((sub.itemsite_qtyonhand * itemsub_uomratio) + (qtyOrdered(sub.itemsite_id, (<? value("date") ?> - CURRENT_DATE)) * itemsub_uomratio)
+             ((qtyAvailable(sub.itemsite_id) * itemsub_uomratio) + (qtyOrdered(sub.itemsite_id, (<? value("date") ?> - CURRENT_DATE)) * itemsub_uomratio)
               - (qtyAllocated(sub.itemsite_id, (<? value("date") ?> - CURRENT_DATE)) * itemsub_uomratio)) AS available
   <? else ?>
              (qtyAllocated(sub.itemsite_id, (<? value("date") ?> - CURRENT_DATE))) AS allocated,
              (qtyOrdered(sub.itemsite_id, (<? value("date") ?> - CURRENT_DATE))) AS ordered,
-             (sub.itemsite_qtyonhand + qtyOrdered(sub.itemsite_id,
+             (qtyAvailable(sub.itemsite_id) + qtyOrdered(sub.itemsite_id,
              (<? value("date") ?> - CURRENT_DATE)) - qtyAllocated(sub.itemsite_id, (<? value("date") ?> - CURRENT_DATE))) AS available
   <? endif ?>
 <? endif ?>
index 99f8b82..f49f608 100644 (file)
@@ -8,19 +8,14 @@ SELECT itemsite_id, warehous_code, item_number,
        (item_descrip1 || ' ' || item_descrip2) AS itemdescrip, uom_name,
        itemsite_qtyonhand,
        detailedQOH(itemsite_id, FALSE) AS detailedqoh,
-       itemsite_nnqoh,
-       detailedNNQOH(itemsite_id, FALSE) AS detailednnqoh,
        'qty' AS itemsite_qtyonhand_xtnumericrole,
-       'qty' AS detailedqoh_xtnumericrole,
-       'qty' AS itemsite_nnqoh_xtnumericrole,
-       'qty' AS detailednnqoh_xtnumericrole
+       'qty' AS detailedqoh_xtnumericrole
 FROM whsinfo, item, itemsite, uom
 WHERE ( (itemsite_item_id=item_id)
     AND (item_inv_uom_id=uom_id)
     AND (itemsite_warehous_id=warehous_id)
     AND ((itemsite_loccntrl) OR (itemsite_controlmethod IN ('L', 'S')))
-    AND ((itemsite_qtyonhand <> detailedQOH(itemsite_id, FALSE))
-      OR (itemsite_nnqoh <> detailedNNQOH(itemsite_id, FALSE)))
+    AND (itemsite_qtyonhand <> detailedQOH(itemsite_id, FALSE))
 <? if exists("classcode_id") ?>
     AND (item_classcode_id=<? value("classcode_id") ?>)
 <? elseif exists("classcode_pattern") ?>
index bf8d03a..21c8615 100644 (file)
@@ -1 +1,4 @@
-SELECT setMetric('ServerVersion', '4.7.0Beta');
+-- Proof of concept
+insert into metric (metric_name, metric_value)
+select 'UnifiedBuild', 'true'
+where not exists (select c.metric_id from metric c where c.metric_name = 'UnifiedBuild');
index 12b5c42..0fdcad7 100644 (file)
@@ -51,7 +51,7 @@
              END AS altId,
              item_number, item_descrip1, item_descrip2, item_inv_uom_id,
              warehous_id, warehous_code, itemsite_leadtime,
-             itemsite_qtyonhand AS qtyonhand,
+             qtyAvailable(itemsite_id) AS qtyonhand,
              CASE WHEN itemsite_useparams THEN itemsite_reorderlevel
                   ELSE 0.0
              END AS reorderlevel,
index d0c25b4..9be2630 100644 (file)
@@ -73,7 +73,7 @@
                      cohead_id, cohead_number, cust_number, cust_name,
                      item_number, (item_descrip1 || ' ' || item_descrip2) AS item_description,
                      uom_name, item_picklist,
-                     noNeg(itemsite_qtyonhand) AS qoh,
+                     noNeg(qtyAvailable(itemsite_id)) AS qoh,
                      noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) AS sobalance,
                      qtyAllocated(itemsite_id, coitem_scheddate) AS allocated,
                      qtyOrdered(itemsite_id, coitem_scheddate) AS ordered,
@@ -95,7 +95,7 @@
                   AND (wo_status IN ('E','R','I'))
                   AND (wo_qtyord-wo_qtyrcv > 0)
                   AND (noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned-qtyatshipping(coitem_id)) > 
-                        (SELECT itemsite_qtyonhand FROM itemsite WHERE (itemsite_id=coitem_itemsite_id))))
+                        (SELECT qtyAvailable(itemsite_id) AS availableqoh FROM itemsite WHERE (itemsite_id=coitem_itemsite_id))))
 &lt;? endif ?>
                 WHERE((coitem_cohead_id=cohead_id)
                   AND (cohead_cust_id=cust_id)
index 794fc0a..251dcf4 100644 (file)
@@ -62,7 +62,7 @@
                  FROM ( SELECT itemsite_id, coitem_id,
                                item_number, (item_descrip1 || ' ' || item_descrip2) AS item_description,
                                uom_name, item_picklist,
-                               noNeg(itemsite_qtyonhand) AS qoh,
+                               noNeg(qtyAvailable(itemsite_id)) AS qoh,
                                noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) AS sobalance,
                                qtyAllocated(itemsite_id, coitem_scheddate) AS allocated,
                                qtyOrdered(itemsite_id, coitem_scheddate) AS ordered,
@@ -83,7 +83,7 @@
                               AND (wo_status IN ('E','R','I'))
                               AND (wo_qtyord-wo_qtyrcv > 0)
                               AND (noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned-qtyatshipping(coitem_id)) > 
-                               (SELECT itemsite_qtyonhand FROM itemsite WHERE (itemsite_id=coitem_itemsite_id))))
+                               (SELECT qtyAvailable(itemsite_id) AS availableqoh FROM itemsite WHERE (itemsite_id=coitem_itemsite_id))))
                  &lt;? endif ?>
                         WHERE ( (coitem_cohead_id=cohead_id)
                          AND (coitem_itemsite_id=itemsite_id)
index 4d2e2d6..c4571a9 100644 (file)
@@ -55,7 +55,7 @@
              END AS altId,
              item_number, item_descrip1, item_descrip2, item_inv_uom_id,
              warehous_id, warehous_code, itemsite_leadtime,
-             itemsite_qtyonhand AS qtyonhand,
+             qtyAvailable(itemsite_id) AS qtyonhand,
              CASE WHEN itemsite_useparams THEN itemsite_reorderlevel
                   ELSE 0.0
              END AS reorderlevel,
index 48fb294..c547834 100644 (file)
@@ -136,7 +136,7 @@ SELECT shiphead_number, 'T/O #:' AS ordertype,
                                              AND  (invcitem_warehous_id=itemsite_warehous_id)
                                              AND  (invcitem_linenumber=coitem_linenumber)
                                              AND  (cohead_id=coitem_cohead_id))) > 0)) THEN 'P'
-            WHEN (coitem_status='O' AND (itemsite_qtyonhand - qtyAllocated(itemsite_id, CURRENT_DATE)
+            WHEN (coitem_status='O' AND (qtyAvailable(itemsite_id) - qtyAllocated(itemsite_id, CURRENT_DATE)
                                          + qtyOrdered(itemsite_id, CURRENT_DATE))
                                           >= (coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned)) THEN 'R'
             ELSE coitem_status
index e310daf..5d0a545 100644 (file)
@@ -41,7 +41,7 @@
   <sql>SELECT warehous_code, item_number, item_descrip1, item_descrip2,
        formatDate(reorderdate) AS f_reorderdate,
        formatQty(reorderlevel) AS f_reorderlevel,
-       formatQty((itemsite_qtyonhand - qtyAllocated(itemsite_id, reorderdate) + qtyOrdered(itemsite_id, reorderdate))) AS f_projavail,
+       formatQty((qtyNetable(itemsite_id) - qtyAllocated(itemsite_id, reorderdate) + qtyOrdered(itemsite_id, reorderdate))) AS f_projavail,
        reorderdate 
   FROM ( SELECT itemsite_id,
                 CASE WHEN (item_type IN ('M', 'B', 'T')) THEN 1
                      ELSE 3
                 END AS itemtype,
                 warehous_code, item_number, item_descrip1, item_descrip2,
-                reorderDate(itemsite_id, &lt;? value(&quot;lookAheadDays&quot;) ?>, &lt;? if exists(&quot;includePlannedOrder&quot;) ?>true&lt;? else ?>false&lt;? endif ?>) AS reorderdate, itemsite_qtyonhand,
+                reorderDate(itemsite_id, &lt;? value(&quot;lookAheadDays&quot;) ?>, &lt;? if exists(&quot;includePlannedOrder&quot;) ?>true&lt;? else ?>false&lt;? endif ?>) AS reorderdate,
                 reorderlevel 
            FROM ( SELECT itemsite_id, itemsite_item_id, itemsite_warehous_id,
-                         itemsite_qtyonhand,
                          CASE WHEN(itemsite_useparams) THEN itemsite_reorderlevel ELSE 0.0 END AS reorderlevel
                     FROM itemsite 
                    WHERE ((true)
index 04dd1b2..cd649f0 100644 (file)
@@ -41,7 +41,7 @@
  <querysource>
   <name>info</name>
   <sql>SELECT
-       formatQty(itemsite_qtyonhand) AS qoh,
+       formatQty(qtyAvailable(itemsite_id)) AS qoh,
        formatQty(CASE WHEN(itemsite_useparams) THEN itemsite_reorderlevel ELSE 0.0 END) AS reorderlevel,
        formatQty(CASE WHEN(itemsite_useparams) THEN itemsite_ordertoqty ELSE 0.0 END) AS ordertoqty,
        formatQty(CASE WHEN(itemsite_useparams) THEN itemsite_multordqty ELSE 0.0 END) AS multorderqty 
index 0a9d355..4a5c328 100644 (file)
        item_number,
        item_descrip1,
        item_descrip2,
-       formatQty(sub.itemsite_qtyonhand) AS f_qtyonhand,
+       formatQty(qtyAvailable(sub.itemsite_id)) AS f_qtyonhand,
        formatQty(CASE WHEN(sub.itemsite_useparams) THEN sub.itemsite_reorderlevel ELSE 0.0 END) AS f_reorderlevel,
        sub.itemsite_leadtime as leadtime,
 &lt;? if exists(&quot;byDays&quot;) ?>
        formatQty(qtyAllocated(sub.itemsite_id, &lt;? value(&quot;byDays&quot;) ?>)) AS f_allocated,
        formatQty(qtyOrdered(sub.itemsite_id, &lt;? value(&quot;byDays&quot;) ?>)) AS f_ordered,
-       formatQty(sub.itemsite_qtyonhand + qtyOrdered(sub.itemsite_id, &lt;? value(&quot;byDays&quot;) ?>) - qtyAllocated(sub.itemsite_id, &lt;? value(&quot;byDays&quot;) ?>)) as f_avail
+       formatQty(qtyAvailable(sub.itemsite_id) + qtyOrdered(sub.itemsite_id, &lt;? value(&quot;byDays&quot;) ?>) - qtyAllocated(sub.itemsite_id, &lt;? value(&quot;byDays&quot;) ?>)) as f_avail
 &lt;? elseif exists(&quot;byDate&quot;) ?>
        formatQty(qtyAllocated(sub.itemsite_id, (&lt;? value(&quot;byDate&quot;) ?> - CURRENT_DATE))) AS f_allocated,
        formatQty(qtyOrdered(sub.itemsite_id, (&lt;? value(&quot;byDate&quot;) ?> - CURRENT_DATE))) AS f_ordered,
-       formatQty(sub.itemsite_qtyonhand + qtyOrdered(sub.itemsite_id, (&lt;? value(&quot;byDate&quot;) ?> - CURRENT_DATE)) - qtyAllocated(sub.itemsite_id, (&lt;? value(&quot;byDate&quot;) ?> - CURRENT_DATE))) as f_avail
+       formatQty(qtyAvailable(sub.itemsite_id) + qtyOrdered(sub.itemsite_id, (&lt;? value(&quot;byDate&quot;) ?> - CURRENT_DATE)) - qtyAllocated(sub.itemsite_id, (&lt;? value(&quot;byDate&quot;) ?> - CURRENT_DATE))) as f_avail
 &lt;? else ?>
        formatQty(qtyAllocated(sub.itemsite_id, sub.itemsite_leadtime)) AS f_allocated,
        formatQty(qtyOrdered(sub.itemsite_id, sub.itemsite_leadtime)) AS f_ordered,
-       formatQty(sub.itemsite_qtyonhand + qtyOrdered(sub.itemsite_id, sub.itemsite_leadtime) - qtyAllocated(sub.itemsite_id, sub.itemsite_leadtime)) as f_avail
+       formatQty(qtyAvailable(sub.itemsite_id) + qtyOrdered(sub.itemsite_id, sub.itemsite_leadtime) - qtyAllocated(sub.itemsite_id, sub.itemsite_leadtime)) as f_avail
 &lt;? endif ?>
   FROM item, itemsite AS sub, itemsite AS root, whsinfo, itemsub
  WHERE ((sub.itemsite_item_id=item_id)
diff --git a/foundation-database/public/tables/setVersion.sql b/foundation-database/public/tables/setVersion.sql
new file mode 100644 (file)
index 0000000..bf8d03a
--- /dev/null
@@ -0,0 +1 @@
+SELECT setMetric('ServerVersion', '4.7.0Beta');
index 6a726da..e8f6d14 100644 (file)
@@ -8,7 +8,8 @@ DECLARE
 BEGIN
 
   -- Cache some information
-  SELECT item_type INTO _r
+  -- Added item_number as part of feature request 21645
+  SELECT item_type, item_number INTO _r
   FROM item
   WHERE (item_id=NEW.itemsite_item_id);
  
@@ -44,11 +45,11 @@ BEGIN
     END IF;
   END IF;
 
+-- Added item_number to error messages displayed to fulfill Feature Request 21645
   IF (NEW.itemsite_qtyonhand < 0 AND NEW.itemsite_costmethod = 'A') THEN
-    RAISE EXCEPTION 'Itemsite (%) is set to use average costing and is not allowed to have a negative quantity on hand.', NEW.itemsite_id;
+    RAISE EXCEPTION 'Itemsite (%) is set to use average costing and is not allowed to have a negative quantity on hand.', 'ID: ' || NEW.itemsite_id || ', Item: ' || _r.item_number;
   ELSIF (NEW.itemsite_value < 0 AND NEW.itemsite_costmethod = 'A') THEN
-    RAISE EXCEPTION 'This transaction results in a negative itemsite value.  Itemsite (%) is set to use average costing and is not allowed to have a negative value.', NEW.itemsite_id;
-  END IF;
+    RAISE EXCEPTION 'This transaction results in a negative itemsite value.  Itemsite (%) is set to use average costing and is not allowed to have a negative value.', 'ID: ' || NEW.itemsite_id || ', Item: ' || _r.item_number;  END IF;
 
 --  Handle the ChangeLog
   IF ( SELECT (metric_value='t')
@@ -364,19 +365,6 @@ BEGIN
 
         RAISE NOTICE 'Deleting item site detail records,';
 
-        SELECT SUM(itemloc_qty) INTO _qty
-        FROM itemloc, location
-        WHERE ((itemloc_location_id=location_id)
-        AND (NOT location_netable) 
-        AND (itemloc_itemsite_id=OLD.itemsite_id));
-
-        IF (_qty != 0) THEN
-          UPDATE itemsite
-          SET itemsite_qtyonhand = itemsite_qtyonhand + _qty,
-            itemsite_nnqoh = itemsite_nnqoh - _qty
-          WHERE (itemsite_id=OLD.itemsite_id);
-        END IF;
-
         DELETE FROM itemloc
         WHERE (itemloc_itemsite_id=OLD.itemsite_id);
       END IF;
index 9c78831..c82a0f6 100644 (file)
@@ -82,23 +82,6 @@ DECLARE
 
 BEGIN
 
-  -- Maintain itemsite_qtyonhand and itemsite_nnqoh when location_netable changes
-  IF (TG_OP = 'UPDATE') THEN
-    IF (OLD.location_netable <> NEW.location_netable) THEN
-      FOR _itemloc IN SELECT * FROM itemloc WHERE (itemloc_location_id=NEW.location_id) LOOP
-        IF (NEW.location_netable) THEN
-          UPDATE itemsite SET itemsite_qtyonhand = itemsite_qtyonhand + _itemloc.itemloc_qty,
-                              itemsite_nnqoh = itemsite_nnqoh - _itemloc.itemloc_qty
-          WHERE (itemsite_id=_itemloc.itemloc_itemsite_id);
-        ELSE
-          UPDATE itemsite SET itemsite_qtyonhand = itemsite_qtyonhand - _itemloc.itemloc_qty,
-                              itemsite_nnqoh = itemsite_nnqoh + _itemloc.itemloc_qty
-          WHERE (itemsite_id=_itemloc.itemloc_itemsite_id);
-        END IF;
-      END LOOP;
-    END IF;
-  END IF;
-  
   RETURN NEW;
 
 END;
index ffbd2a8..a2371b6 100644 (file)
@@ -56,6 +56,9 @@
 @defaultPanelWidth: 320px;
 @toolbarHeight: 55px;
 @searchLength: 185px;
+// popups
+@maxMessageHeight: 500px;
+@maxMessageWidth: 500px;
 
 // libs
 @import "../../lib/font-awesome/less/font-awesome.less";
@@ -196,13 +199,16 @@ a, .hyperlink {
 */
 .xv-popup {
   background: @header-gray;
-  margin: 0;
-  max-height: 400px;
-  width: 400px;
   min-width: @defaultPanelWidth;
-  padding: 7px;
+  padding: 10px;
   text-align: center;
 
+  .message {
+    margin-bottom: 10px;
+    max-height: @maxMessageHeight;
+    max-width: @maxMessageWidth;
+  }
+
   &.xv-groupbox-popup {
     .xv-workspace-container > .xv-workspace > .xv-workspace-panel;
     color: @black;
index 62aa1aa..f123de5 100755 (executable)
@@ -1628,13 +1628,15 @@ a,
 */
 .xv-popup {
   background: #505050;
-  margin: 0;
-  max-height: 400px;
-  width: 400px;
   min-width: 320px;
-  padding: 7px;
+  padding: 10px;
   text-align: center;
 }
+.xv-popup .message {
+  margin-bottom: 10px;
+  max-height: 500px;
+  max-width: 500px;
+}
 .xv-popup.xv-groupbox-popup {
   width: 320px;
   margin: 0 4px 0 2px;
   border: none;
 }
 /**
-  Styles relating to Lists
-*/
-.xv-list-header {
-  background-color: #d8d8d8;
-  color: #fdfdfd;
-  font-size: .6em;
-  font-weight: bold;
-  text-transform: uppercase;
-  padding-top: 4px;
-  padding-bottom: 4px;
-  border-bottom: 1px solid #aaaaaa;
+ * Default ListItem styles when using a ModelDecorator.
+ */
+.xv-list .xv-model-decorator > .xv-list-item .xv-table {
+  display: table;
+  width: 100%;
+  table-layout: fixed;
 }
-.xv-list-header .xv-list-column.last {
-  border-right: none;
+.xv-list .xv-model-decorator > .xv-list-item .xv-table .xv-cell {
+  display: table-cell;
 }
-.xv-list-header .xv-list-column.name-column,
-.xv-list-header .xv-list-column.first,
-.xv-list-header .xv-list-column.second,
-.xv-list-header .xv-list-column.third,
-.xv-list-header .xv-list-column.short,
-.xv-list-header .xv-list-column.small,
-.xv-list-header .xv-list-column.medium,
-.xv-list-header .xv-list-column.descr {
-  padding-left: 7px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr {
+  /**
+        * Default styling for a model's id (as designated by 'idAttribute')
+        */
 }
-/* List */
-.xv-list-column.line-number {
-  width: 30px;
-  text-align: right;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-id {
+  color: #357ec7;
+  font-weight: bold;
+  cursor: pointer;
 }
-.xv-list-column.name-column {
-  width: 200px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-name {
+  font-weight: bold;
 }
-.xv-list-column.right-column {
-  width: 100px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-number {
   text-align: right;
 }
-.xv-list-column.short {
-  width: 100px;
-}
-.xv-list-column.small {
-  width: 125px;
-}
-.xv-list-column.medium {
-  width: 150px;
-}
-.xv-list-column.first {
-  width: 300px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-money {
+  text-align: right;
 }
-.xv-list-column.second {
-  width: 200px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-date {
+  text-align: right;
 }
-.xv-list-column.third {
-  width: 100px;
+.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr {
+  color: white;
 }
-.xv-list-column.money,
-.xv-list-column.quantity {
-  width: 75px;
-  text-align: right;
+.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr.xm-attribute-id {
+  color: #ff6529;
 }
-.xv-list-column.descr {
-  width: 200px;
+/**
+  Styles related to pickers, combo boxes, and relation widgets
+*/
+.onyx-picker-decorator .onyx-button {
+  padding: 12px 8px 12px 8px;
+  width: 150px;
 }
-.xv-list-column.icon {
-  width: 10px;
+.onyx-picker .onyx-menu-item {
+  text-align: left;
+  text-overflow: ellipsis;
 }
-.xv-list {
-  background: #f8f8f8;
+.picker-icon {
+  position: absolute;
+  right: 0;
+  margin: 0 10px 0 2px;
+  color: #070707;
 }
-.xv-list .xv-list-item > * {
-  display: inline-block;
-  vertical-align: middle;
+.xv-picker-button {
+  text-align: left;
 }
-.xv-list .xv-list-item {
-  background-color: #fdfdfd;
-  border-bottom: 1px solid #d7d7d7;
-  min-height: 32px;
+.xv-picker-button .picker-content {
+  max-width: 100px;
+  overflow: hidden;
 }
-.xv-list .xv-list-item.header {
-  padding-top: 0;
+.xv-picker-button.disabled {
+  color: #777777;
 }
-.xv-list .xv-list-item.inactive {
-  background-color: #d8d8d8;
+.xv-picker-label {
   color: #070707;
+  padding: 20px 8px 8px 8px;
+  text-align: right;
+  width: 130px;
 }
-.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr {
-  background: transparent;
-}
-.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr.placeholder {
-  color: #d8d8d8;
+.xv-picker-label.disabled {
+  color: #777777;
 }
-.xv-list .xv-list-item .xv-list-column .list-icon {
-  padding: 2px;
-  color: #666666;
-  vertical-align: sub;
-  border: 1px solid #efefef;
-  -webkit-border-radius: 2px;
-  -moz-border-radius: 2px;
-  border-radius: 2px;
+.xv-combobox-note {
+  padding: 14px 3px 8px 3px;
+  text-align: left;
 }
-.xv-list .xv-list-item.item-selected {
-  background: #226b9a;
-  background-color: #1f608c;
-  background-image: -moz-linear-gradient(top, #226b9a, #1a4f77);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77));
-  background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77);
-  background-image: -o-linear-gradient(top, #226b9a, #1a4f77);
-  background-image: linear-gradient(to bottom, #226b9a, #1a4f77);
-  background-repeat: repeat-x;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0);
+/*
+  Styles relating to the grid box
+*/
+/* Entire box including the grid and the summary panel */
+.xv-grid-box {
+  /**
+    This is the most general grid row that
+    is not specific to read-only or selected
+  */
 }
-.xv-list .xv-list-item.item-selected .xv-list-attr {
-  color: #fdfdfd;
+.xv-grid-box.small-panel {
+  width: 600px;
 }
-.xv-list .xv-list-item.item-selected .xv-list-attr.placeholder {
-  font-style: italic;
-  color: #99ccff;
+.xv-grid-box.medium-panel {
+  width: 700px;
 }
-.xv-list .xv-list-item.item-selected .xv-list-attr.hyperlink {
-  color: #ff6529;
+.xv-grid-box.large-panel {
+  width: 800px;
 }
-.xv-list .xv-list-item.item-selected .xv-list-attr.header {
-  background: #99ccff;
+.xv-grid-box .enyo-list-page > *:first-child .xv-grid-row {
+  border-top: 0;
 }
-.xv-list .xv-list-item .xv-list-item-gear {
-  position: absolute;
-  right: 0px;
-  z-index: 999;
+.xv-grid-box .xv-above-grid-list {
+  border: 0;
 }
-.xv-list.xv-grid-list {
+.xv-grid-box .xv-scroller {
   background: #f8f8f8;
 }
-.xv-list.xv-grid-list .xv-list-item > * {
-  vertical-align: top;
+.xv-limit-description .xv-grid-box .xv-grid-attr.bold {
+  font-weight: bold;
 }
-.xv-list.xv-grid-list .xv-list-item {
-  padding-top: 7px !important;
-  padding-bottom: 9px !important;
-  border-bottom: 1px solid #aaaaaa !important;
-  background: #f8f8f8;
+.xv-grid-box .xv-grid-attr.error {
+  color: #ff0000;
 }
-.xv-list.xv-grid-list .xv-list-item.item-selected {
-  background: #226b9a;
-  background-color: #1f608c;
-  background-image: -moz-linear-gradient(top, #226b9a, #1a4f77);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77));
-  background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77);
-  background-image: -o-linear-gradient(top, #226b9a, #1a4f77);
-  background-image: linear-gradient(to bottom, #226b9a, #1a4f77);
-  background-repeat: repeat-x;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0);
+.xv-grid-box .xv-grid-attr.emphasis {
+  color: #009000;
 }
-.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr {
-  color: #fdfdfd;
+.xv-grid-box .xv-grid-attr.warn {
+  color: #ff9c00;
 }
-.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.placeholder {
+.xv-grid-box .xv-grid-attr.italic {
   font-style: italic;
-  color: #99ccff;
 }
-.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.hyperlink {
-  color: #ff6529;
+.xv-grid-box .xv-grid-attr.placeholder {
+  font-style: italic;
+  color: #93a1a1;
 }
-.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.header {
-  background: #99ccff;
+.xv-grid-box .xv-grid-attr.hyperlink {
+  color: blue;
 }
-.xv-list.xv-grid-list .xv-list-item .xv-list-column {
-  vertical-align: top;
+.xv-grid-box .xv-gridbox-button {
+  color: #357ec7;
+  font-size: 18px;
+  border: none;
+  background: transparent;
 }
-.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr {
+.xv-grid-box .xv-grid-row {
   font-size: 12px;
+  background-color: #d8d8d8;
+  border-bottom: 1px solid #aaaaaa;
+  vertical-align: top;
+  /**
+      This is the grid header row
+    */
 }
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.last {
-  border-right: none;
+.xv-grid-box .xv-grid-row > * {
+  display: inline-block;
 }
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.name-column {
-  padding-left: 7px;
+.xv-grid-box .xv-grid-row .xv-grid-header {
+  background-color: #d7d7d7;
+  color: #0e0e0e;
+  font-size: .8em;
+  font-weight: bold;
+  text-transform: uppercase;
+  padding-top: 4px;
 }
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.first {
-  padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.second {
-  padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.third {
-  padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.short {
-  padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.small {
-  padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.medium {
-  padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.descr {
-  padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr {
-  padding: 0px;
-}
-.xv-list-attr {
-  padding: 5px;
-  font-size: .8em;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  color: #070707;
-}
-.xv-list-attr.header {
-  padding: 4px;
-  background: #d8d8d8;
-  font-size: .7em;
-  font-weight: bold;
-  text-transform: uppercase;
-  color: #fdfdfd;
-}
-.xv-list-attr.footer {
-  padding: 4px;
-  background: #d8d8d8;
-  font-size: .7em;
-  font-weight: bold;
-  text-transform: uppercase;
-  color: #070707;
-}
-.xv-list-attr.right {
-  position: absolute;
-  right: 10px;
-}
-.xv-list-attr.text-align-right {
-  text-align: right;
-}
-.xv-list-attr.bold {
-  font-weight: bold;
-}
-.xv-list-attr.error {
-  color: #ff0000;
-}
-.xv-list-attr.emphasis {
-  color: #009000;
-}
-.xv-list-attr.warn {
-  color: #ff9c00;
-}
-.xv-list-attr.italic {
-  font-style: italic;
-}
-.xv-list-attr.placeholder {
-  font-style: italic;
-  color: #777777;
-}
-.xv-list-attr.hyperlink {
-  color: #357ec7;
-  cursor: pointer;
-}
-.xv-list-attr.disabled {
-  color: #777777;
-}
-/* Navigator */
-.xv-navigator-header {
-  font-size: small;
-  font-weight: bold;
-  text-transform: uppercase;
-  color: #ff6600;
-  padding-left: 20px;
-  border-bottom: 1px solid #0e0e0e;
-}
-.xv-workspace-header {
-  color: #fdfdfd;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  padding: 8px 0 0 8px;
-}
-/**
- * Default ListItem styles when using a ModelDecorator.
- */
-.xv-list .xv-model-decorator > .xv-list-item .xv-table {
-  display: table;
-  width: 100%;
-  table-layout: fixed;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-table .xv-cell {
-  display: table-cell;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr {
-  /**
-        * Default styling for a model's id (as designated by 'idAttribute')
-        */
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-id {
-  color: #357ec7;
-  font-weight: bold;
-  cursor: pointer;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-name {
-  font-weight: bold;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-number {
-  text-align: right;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-money {
-  text-align: right;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-date {
-  text-align: right;
-}
-.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr {
-  color: white;
-}
-.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr.xm-attribute-id {
-  color: #ff6529;
-}
-/**
-  Styles related to pickers, combo boxes, and relation widgets
-*/
-.onyx-picker-decorator .onyx-button {
-  padding: 12px 8px 12px 8px;
-  width: 150px;
-}
-.onyx-picker .onyx-menu-item {
-  text-align: left;
-  text-overflow: ellipsis;
-}
-.picker-icon {
-  position: absolute;
-  right: 0;
-  margin: 0 10px 0 2px;
-  color: #070707;
-}
-.xv-picker-button {
-  text-align: left;
-}
-.xv-picker-button .picker-content {
-  max-width: 100px;
-  overflow: hidden;
-}
-.xv-picker-button.disabled {
-  color: #777777;
-}
-.xv-picker-label {
-  color: #070707;
-  padding: 20px 8px 8px 8px;
-  text-align: right;
-  width: 130px;
-}
-.xv-picker-label.disabled {
-  color: #777777;
-}
-.xv-combobox-note {
-  padding: 14px 3px 8px 3px;
-  text-align: left;
-}
-/*
-  Styles relating to the grid box
-*/
-/* Entire box including the grid and the summary panel */
-.xv-grid-box {
-  /**
-    This is the most general grid row that
-    is not specific to read-only or selected
-  */
-}
-.xv-grid-box.small-panel {
-  width: 600px;
-}
-.xv-grid-box.medium-panel {
-  width: 700px;
-}
-.xv-grid-box.large-panel {
-  width: 800px;
-}
-.xv-grid-box .enyo-list-page > *:first-child .xv-grid-row {
-  border-top: 0;
-}
-.xv-grid-box .xv-above-grid-list {
-  border: 0;
-}
-.xv-grid-box .xv-scroller {
-  background: #f8f8f8;
-}
-.xv-limit-description .xv-grid-box .xv-grid-attr.bold {
-  font-weight: bold;
-}
-.xv-grid-box .xv-grid-attr.error {
-  color: #ff0000;
-}
-.xv-grid-box .xv-grid-attr.emphasis {
-  color: #009000;
-}
-.xv-grid-box .xv-grid-attr.warn {
-  color: #ff9c00;
-}
-.xv-grid-box .xv-grid-attr.italic {
-  font-style: italic;
-}
-.xv-grid-box .xv-grid-attr.placeholder {
-  font-style: italic;
-  color: #93a1a1;
-}
-.xv-grid-box .xv-grid-attr.hyperlink {
-  color: blue;
-}
-.xv-grid-box .xv-gridbox-button {
-  color: #357ec7;
-  font-size: 18px;
-  border: none;
-  background: transparent;
-}
-.xv-grid-box .xv-grid-row {
-  font-size: 12px;
-  background-color: #d8d8d8;
-  border-bottom: 1px solid #aaaaaa;
-  vertical-align: top;
-  /**
-      This is the grid header row
-    */
-}
-.xv-grid-box .xv-grid-row > * {
-  display: inline-block;
-}
-.xv-grid-box .xv-grid-row .xv-grid-header {
-  background-color: #d7d7d7;
-  color: #0e0e0e;
-  font-size: .8em;
-  font-weight: bold;
-  text-transform: uppercase;
-  padding-top: 4px;
-}
-.xv-grid-box .xv-grid-row .xv-grid-header.last {
-  border-right: none;
+.xv-grid-box .xv-grid-row .xv-grid-header.last {
+  border-right: none;
 }
 .xv-grid-box .xv-grid-row > * {
   padding: 6px 4px;
@@ -2960,6 +2687,281 @@ a,
   text-align: center;
   font-size: 24px;
 }
+/**
+  Styles relating to Lists
+*/
+.xv-list-header {
+  background-color: #d8d8d8;
+  color: #fdfdfd;
+  font-size: .6em;
+  font-weight: bold;
+  text-transform: uppercase;
+  padding-top: 4px;
+  padding-bottom: 4px;
+  border-bottom: 1px solid #aaaaaa;
+}
+.xv-list-header .xv-list-column.last {
+  border-right: none;
+}
+.xv-list-header .xv-list-column.name-column,
+.xv-list-header .xv-list-column.first,
+.xv-list-header .xv-list-column.second,
+.xv-list-header .xv-list-column.third,
+.xv-list-header .xv-list-column.short,
+.xv-list-header .xv-list-column.small,
+.xv-list-header .xv-list-column.medium,
+.xv-list-header .xv-list-column.descr {
+  padding-left: 7px;
+}
+/* List */
+.xv-list-column.line-number {
+  width: 30px;
+  text-align: right;
+}
+.xv-list-column.name-column {
+  width: 200px;
+}
+.xv-list-column.right-column {
+  width: 100px;
+  text-align: right;
+}
+.xv-list-column.short {
+  width: 100px;
+}
+.xv-list-column.small {
+  width: 125px;
+}
+.xv-list-column.medium {
+  width: 150px;
+}
+.xv-list-column.first {
+  width: 300px;
+}
+.xv-list-column.second {
+  width: 200px;
+}
+.xv-list-column.third {
+  width: 100px;
+}
+.xv-list-column.money,
+.xv-list-column.quantity {
+  width: 75px;
+  text-align: right;
+}
+.xv-list-column.descr {
+  width: 200px;
+}
+.xv-list-column.icon {
+  width: 10px;
+}
+.xv-list {
+  background: #f8f8f8;
+}
+.xv-list .xv-list-item > * {
+  display: inline-block;
+  vertical-align: middle;
+}
+.xv-list .xv-list-item {
+  background-color: #fdfdfd;
+  border-bottom: 1px solid #d7d7d7;
+  min-height: 32px;
+}
+.xv-list .xv-list-item.header {
+  padding-top: 0;
+}
+.xv-list .xv-list-item.inactive {
+  background-color: #d8d8d8;
+  color: #070707;
+}
+.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr {
+  background: transparent;
+}
+.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr.placeholder {
+  color: #d8d8d8;
+}
+.xv-list .xv-list-item .xv-list-column .list-icon {
+  padding: 2px;
+  color: #666666;
+  vertical-align: sub;
+  border: 1px solid #efefef;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+}
+.xv-list .xv-list-item.item-selected {
+  background: #226b9a;
+  background-color: #1f608c;
+  background-image: -moz-linear-gradient(top, #226b9a, #1a4f77);
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77));
+  background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77);
+  background-image: -o-linear-gradient(top, #226b9a, #1a4f77);
+  background-image: linear-gradient(to bottom, #226b9a, #1a4f77);
+  background-repeat: repeat-x;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0);
+}
+.xv-list .xv-list-item.item-selected .xv-list-attr {
+  color: #fdfdfd;
+}
+.xv-list .xv-list-item.item-selected .xv-list-attr.placeholder {
+  font-style: italic;
+  color: #99ccff;
+}
+.xv-list .xv-list-item.item-selected .xv-list-attr.hyperlink {
+  color: #ff6529;
+}
+.xv-list .xv-list-item.item-selected .xv-list-attr.header {
+  background: #99ccff;
+}
+.xv-list .xv-list-item .xv-list-item-gear {
+  position: absolute;
+  right: 0px;
+  z-index: 999;
+}
+.xv-list.xv-grid-list {
+  background: #f8f8f8;
+}
+.xv-list.xv-grid-list .xv-list-item > * {
+  vertical-align: top;
+}
+.xv-list.xv-grid-list .xv-list-item {
+  padding-top: 7px !important;
+  padding-bottom: 9px !important;
+  border-bottom: 1px solid #aaaaaa !important;
+  background: #f8f8f8;
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected {
+  background: #226b9a;
+  background-color: #1f608c;
+  background-image: -moz-linear-gradient(top, #226b9a, #1a4f77);
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77));
+  background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77);
+  background-image: -o-linear-gradient(top, #226b9a, #1a4f77);
+  background-image: linear-gradient(to bottom, #226b9a, #1a4f77);
+  background-repeat: repeat-x;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0);
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr {
+  color: #fdfdfd;
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.placeholder {
+  font-style: italic;
+  color: #99ccff;
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.hyperlink {
+  color: #ff6529;
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.header {
+  background: #99ccff;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column {
+  vertical-align: top;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr {
+  font-size: 12px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.last {
+  border-right: none;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.name-column {
+  padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.first {
+  padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.second {
+  padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.third {
+  padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.short {
+  padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.small {
+  padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.medium {
+  padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.descr {
+  padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr {
+  padding: 0px;
+}
+.xv-list-attr {
+  padding: 5px;
+  font-size: .8em;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  color: #070707;
+}
+.xv-list-attr.header {
+  padding: 4px;
+  background: #d8d8d8;
+  font-size: .7em;
+  font-weight: bold;
+  text-transform: uppercase;
+  color: #fdfdfd;
+}
+.xv-list-attr.footer {
+  padding: 4px;
+  background: #d8d8d8;
+  font-size: .7em;
+  font-weight: bold;
+  text-transform: uppercase;
+  color: #070707;
+}
+.xv-list-attr.right {
+  position: absolute;
+  right: 10px;
+}
+.xv-list-attr.text-align-right {
+  text-align: right;
+}
+.xv-list-attr.bold {
+  font-weight: bold;
+}
+.xv-list-attr.error {
+  color: #ff0000;
+}
+.xv-list-attr.emphasis {
+  color: #009000;
+}
+.xv-list-attr.warn {
+  color: #ff9c00;
+}
+.xv-list-attr.italic {
+  font-style: italic;
+}
+.xv-list-attr.placeholder {
+  font-style: italic;
+  color: #777777;
+}
+.xv-list-attr.hyperlink {
+  color: #357ec7;
+  cursor: pointer;
+}
+.xv-list-attr.disabled {
+  color: #777777;
+}
+/* Navigator */
+.xv-navigator-header {
+  font-size: small;
+  font-weight: bold;
+  text-transform: uppercase;
+  color: #ff6600;
+  padding-left: 20px;
+  border-bottom: 1px solid #0e0e0e;
+}
+.xv-workspace-header {
+  color: #fdfdfd;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  padding: 8px 0 0 8px;
+}
 /**
   Styles relating to widgets in the pullout
 */
index e7ccd5e..7130a80 100644 (file)
@@ -38,19 +38,20 @@ trailing:true, white:true*/
         {name: "startupProgressBar", kind: "onyx.ProgressBar",
           classes: "xv-startup-progress  onyx-progress-button", progress: 0}
       ]},
-      {kind: "onyx.Popup", name: "notifyPopup", centered: true,
+      {kind: "onyx.Popup", name: "notifyPopup", classes: "xv-popup", centered: true,
         onHide: "notifyHidden",
         modal: true, floating: true, scrim: true, components: [
-        {name: "notifyMessage"},
-        {tag: "br"},
-        {kind: "onyx.Button", content: "_ok".loc(), name: "notifyOk", ontap: "notifyTap",
-          classes: "xv-popup-button", showing: false},
-        {kind: "onyx.Button", content: "_yes".loc(), name: "notifyYes", ontap: "notifyTap",
-          classes: "xv-popup-button", showing: false},
-        {kind: "onyx.Button", content: "_no".loc(), name: "notifyNo", ontap: "notifyTap",
-          classes: "xv-popup-button", showing: false},
-        {kind: "onyx.Button", content: "_cancel".loc(), name: "notifyCancel", ontap: "notifyTap",
-          classes: "xv-popup-button", showing: false}
+        {name: "notifyMessage", classes: "message"},
+        {classes: "xv-buttons", name: "notifyButtons", components: [
+          {kind: "onyx.Button", content: "_ok".loc(), name: "notifyOk", ontap: "notifyTap",
+            showing: false, classes: "text"},
+          {kind: "onyx.Button", content: "_yes".loc(), name: "notifyYes", ontap: "notifyTap",
+            showing: false, classes: "text"},
+          {kind: "onyx.Button", content: "_no".loc(), name: "notifyNo", ontap: "notifyTap",
+            showing: false, classes: "text"},
+          {kind: "onyx.Button", content: "_cancel".loc(), name: "notifyCancel", ontap: "notifyTap",
+            showing: false, classes: "text"}
+        ]}
       ]},
       {kind: "onyx.Popup", name: "popupWorkspace", classes: "xv-popup xv-groupbox-popup", centered: true,
         autoDismiss: false, modal: true, floating: true, scrim: true},
@@ -59,7 +60,8 @@ trailing:true, white:true*/
     resizeHandler: function () {
       this.inherited(arguments);
       if (this.$.notifyPopup.showing) {
-        this.$.notifyPopup.applyStyle("opacity", 1); // XXX not sure why this hack is necessary.
+        // This is a fix for an enyo bug that renders the popup as clear
+        this.$.notifyPopup.applyStyle("opacity", 1);
       }
     },
     activate: function () {
@@ -178,9 +180,7 @@ trailing:true, white:true*/
       return this.$.navigator;
     },
     getNotifyButtons: function () {
-      return _.filter(this.$, function (control) {
-        return control.name.substring(0, 6) === 'notify' && control.kind === 'onyx.Button';
-      });
+      return this.$.notifyButtons.controls;
     },
     getStartupProgressBar: function () {
       return this.$.startupProgressBar;
@@ -258,19 +258,10 @@ trailing:true, white:true*/
       inEvent.type = inEvent.type || XM.Model.NOTICE;
 
       // show the appropriate buttons
-      _.each(this.$.notifyPopup.children, function (component) {
-        if (component.kind !== "onyx.Button") {
-          // not a button: do nothing.
-        } else if (_.indexOf(typeToButtonMap[String(inEvent.type)], component.name) >= 0) {
-          // in the show-me array, so show
-          component.setShowing(true);
-        } else {
-          // not in the show-me array, so hide
-          component.setShowing(false);
-        }
+      _.each(this.getNotifyButtons(), function (component) {
+        component.setShowing(_.indexOf(typeToButtonMap[String(inEvent.type)], component.name) >= 0);
       });
 
-
       // allow custom button text
       this.$.notifyYes.setContent(inEvent.yesLabel || "_yes".loc());
       this.$.notifyNo.setContent(inEvent.noLabel || "_no".loc());
@@ -281,7 +272,7 @@ trailing:true, white:true*/
       // it's the OK button unless it's a 2- or 3- way question, in which case it's YES
       this._activeNotify = inEvent.type === XM.Model.QUESTION || inEvent.type === XM.Model.YES_NO_CANCEL ? 1 : 0;
       _.each(this.getNotifyButtons(), function (button, index) {
-        button.addRemoveClass("onyx-blue", index === that._activeNotify);
+        button.addRemoveClass("selected", index === that._activeNotify);
       });
 
       // delete out any previously added customComponents/customComponentControls
@@ -302,9 +293,9 @@ trailing:true, white:true*/
       // Add the custom component
       if (inEvent.component) {
         inEvent.component.name = "customComponent";
-        inEvent.component.addBefore = this.$.notifyOk;
+        // can add styling class here instead of inline css
+        inEvent.component.addBefore = this.$.notifyButtons;
         this.$.notifyPopup.createComponent(inEvent.component);
-        this.$.notifyPopup.$.customComponent.addStyles("color:black;");
         if (inEvent.componentModel) {
           this.$.notifyPopup.$.customComponent.setValue(inEvent.componentModel);
         }
@@ -313,7 +304,8 @@ trailing:true, white:true*/
       this._notifyDone = false;
       this.$.notifyPopup.render();
       this.$.notifyPopup.show();
-      this.$.notifyPopup.applyStyle("opacity", 1); // XXX not sure why this hack is necessary.
+      // Without this fix, the popup renders transparent
+      this.$.notifyPopup.applyStyle("opacity", 1);
     },
     notifyHidden: function () {
       if (!this._notifyDone) {
@@ -331,7 +323,7 @@ trailing:true, white:true*/
 
       } else if (keyCode === 37 || (keyCode === 9 && isShift)) {
         // left or shift-tab
-        notifyButtons[activeIndex].removeClass("onyx-blue");
+        notifyButtons[activeIndex].removeClass("selected");
         for (nextShowing = activeIndex - 1; nextShowing >= 0; nextShowing--) {
           if (nextShowing === 0 && !notifyButtons[nextShowing].showing) {
             // there are no showing buttons to the left
@@ -346,11 +338,11 @@ trailing:true, white:true*/
           activeIndex = nextShowing;
         }
         this._activeNotify = activeIndex;
-        notifyButtons[activeIndex].addClass("onyx-blue");
+        notifyButtons[activeIndex].addClass("selected");
 
       } else if (keyCode === 39 || keyCode === 9) {
         // right or tab
-        notifyButtons[activeIndex].removeClass("onyx-blue");
+        notifyButtons[activeIndex].removeClass("selected");
         for (nextShowing = activeIndex + 1; nextShowing < notifyButtons.length; nextShowing++) {
           if (nextShowing + 1 === notifyButtons.length && !notifyButtons[nextShowing].showing) {
             // there are no showing buttons to the right
@@ -366,7 +358,7 @@ trailing:true, white:true*/
         }
         this._activeNotify = activeIndex;
 
-        notifyButtons[activeIndex].addClass("onyx-blue");
+        notifyButtons[activeIndex].addClass("selected");
       }
     },
     /**
@@ -447,27 +439,31 @@ trailing:true, white:true*/
         maxHeight: "400px",
         horizontal: "hidden"
       }, {owner: this});
-      this.$.popupWorkspace.createComponent({name: "workspace", kind: inEvent.workspace, container: this.$.popupScroller});
+      this.$.popupWorkspace.createComponent({name: "workspace", kind: inEvent.workspace,
+        container: this.$.popupScroller});
+      // TODO: inline css - git rid of it!
       this.$.popupWorkspace.$.workspace.addStyles("color:black;");
       this.$.popupWorkspace.$.workspace.setValue(inEvent.model);
-      this.$.popupWorkspace.createComponent({
+      // create button bar
+      this.$.popupWorkspace.createComponent({classes: "xv-buttons", name: "workspaceButtons"}, {owner: this});
+      this.$.workspaceButtons.createComponents([{
         kind: "onyx.Button",
         content: "_save".loc(),
         name: "popupWorkspaceSave",
         ontap: "popupWorkspaceTap",
-        classes: "onyx-blue xv-popup-button"
-      }, {owner: this});
-      this.$.popupWorkspace.createComponent({
+        classes: "selected text"
+      },
+      {
         kind: "onyx.Button",
         content: "_cancel".loc(),
         name: "popupWorkspaceCancel",
         ontap: "popupWorkspaceTap",
-        classes: "xv-popup-button"
-      }, {owner: this});
-
+        classes: "text"
+      }], {owner: this});
       this.$.popupWorkspace.render();
       this.$.popupWorkspace.show();
-      this.$.popupWorkspace.applyStyle("opacity", 1); // XXX not sure why this hack is necessary.
+      // Without this fix, the popup renders transparent
+      this.$.popupWorkspace.applyStyle("opacity", 1);
     },
     popupWorkspaceTap: function (inSender, inEvent) {
       var model = this.$.popupWorkspace.$.workspace.value,
diff --git a/lib/orm/source/xt/functions/add_comment_type.sql b/lib/orm/source/xt/functions/add_comment_type.sql
new file mode 100644 (file)
index 0000000..5eb067a
--- /dev/null
@@ -0,0 +1,32 @@
+drop function if exists xt.add_comment_type(text, text, text);
+
+create or replace function xt.add_comment_type(text, text, text) returns boolean volatile as $$
+DECLARE
+   _module  ALIAS FOR $1;
+   _comment ALIAS FOR $2;
+   _descr   ALIAS FOR $3;
+   _cmntid INTEGER;
+
+BEGIN
+  SELECT source_id INTO _cmntid
+       FROM source WHERE source_name = _comment;
+
+  IF (NOT FOUND) THEN
+    INSERT INTO source (source_module, source_name, source_descrip)
+      VALUES (_module, _comment, _descr) 
+      RETURNING source_id INTO _cmntid;
+
+  INSERT INTO cmnttypesource (cmnttypesource_cmnttype_id, cmnttypesource_source_id)
+       VALUES (1, _cmntid);  -- General Comments
+  INSERT INTO cmnttypesource (cmnttypesource_cmnttype_id, cmnttypesource_source_id)
+         VALUES (2, _cmntid);  -- ChangeLog Comments
+  
+  END IF;
+
+  RETURN true;
+
+END;
+
+$$ language 'plpgsql';
+
+
index 334a84d..f2b9145 100755 (executable)
@@ -298,6 +298,7 @@ var conditionalExpressSession = function (req, res, next) {
       req.path === "/" ||
       req.path === "/favicon.ico" ||
       req.path === "/forgot-password" ||
+      req.path === '/node_modules/jquery/jquery.js' ||
       req.path === "/recover") {
 
     next();
index b4c69d5..16858d8 100644 (file)
@@ -7,8 +7,7 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
 (function () {
   "use strict";
 
-  var ursa = require("ursa"),
-    exec = require("child_process").exec,
+  var exec = require("child_process").exec,
     forge = require("node-forge"),
     spawn = require("child_process").spawn,
     async = require("async"),
@@ -29,10 +28,7 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
         res.send({isError: true, error: err});
       },
       genKey = function (model, result) {
-        /**
-          * This is REALLY slow in pure javascript. ursa is much faster.
-          * @See: https://github.com/digitalbazaar/forge/issues/125
-        forge.pki.rsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) {
+        forge.pki.rsa.generateKeyPair({bits: 2048, workers: -1}, function (err, keypair) {
           if (err) {
             res.send({isError: true, message: "Error generating keypair: " + err.message, error: err});
             return;
@@ -40,16 +36,6 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
 
           fetchSuccess(model, result, keypair);
         });
-        */
-
-        // Use ursa for the key gen and then convert to forge's format.
-        var keypair = ursa.generatePrivateKey();
-        var keys = {
-          privateKey: forge.pki.privateKeyFromPem(keypair.toPrivatePem().toString()),
-          publicKey: forge.pki.publicKeyFromPem(keypair.toPublicPem().toString())
-        };
-
-        fetchSuccess(model, result, keys);
       },
       sendP12 = function (keys) {
         // It's possible and much easier to generate the p12 file without a
index 4289283..f5fc09b 100644 (file)
@@ -24,9 +24,9 @@
         <form name="loginForm" action="/login" method="post">
           <input type="hidden" id="hash" name="hash">
           <div class="login-label" id="form-fields_idLabel">Username</div>
-          <input class="login-input" id="form-fields_id" name="id" placeholder="Username">
+          <input class="login-input" id="form-fields_id" name="id" placeholder="username">
           <div class="login-label" id="form-fields_passwordLabel">Password</div>
-          <input class="login-input" id="form-fields_password" placeholder="Password" name="password" type="password">
+          <input class="login-input" id="form-fields_password" placeholder="password" name="password" type="password" autocapitalize="off" autocorrect="off">
           <div class="login-label" id="form-fields_databaseLabel">Database</div>
           <select class="login-input" id="form-fields_database" name="database">
           <% for(var i = 0; i < databases.length; i++) { %>
index cd42baa..0435977 100644 (file)
@@ -183,7 +183,6 @@ label.login-message-box.error {
   display: block;
   width: 97%;
   margin: 0;
-  text-transform: lowercase;
   outline: none;
   color: #666666;
   font-smoothing: antialiased;
index f00146a..6e28736 100644 (file)
@@ -113,9 +113,5 @@ XT = { };
     // give any running process the opportunity to save state
     // or log as gracefully as possible
     process.once('exit', _.bind(X.cleanup, X));
-
-    _.forEach(["SIGINT", "SIGHUP", "SIGQUIT", "SIGKILL", "SIGSEGV", "SIGILL"], function (sig) {
-      process.once(sig, _.bind(sighandler, X, sig));
-    });
   });
 }());
index ea6f324..3762709 100644 (file)
@@ -1,50 +1,54 @@
 {
   "name": "xtuple",
-  "version": "4.6.0",
+  "version": "4.7.0-beta",
   "dependencies": {
     "async": {
       "version": "0.2.10",
-      "from": "async@0.2.10"
+      "from": "async@0.2.x",
+      "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
     },
     "backbone": {
       "version": "0.9.10",
-      "from": "https://registry.npmjs.org/backbone/-/backbone-0.9.10.tgz",
+      "from": "backbone@0.9.10",
       "resolved": "https://registry.npmjs.org/backbone/-/backbone-0.9.10.tgz"
     },
     "backbone-relational": {
       "version": "0.8.0",
-      "from": "https://registry.npmjs.org/backbone-relational/-/backbone-relational-0.8.0.tgz",
-      "resolved": "https://registry.npmjs.org/backbone-relational/-/backbone-relational-0.8.0.tgz"
+      "from": "backbone-relational@0.8.0"
     },
     "bcrypt": {
       "version": "0.7.8",
-      "from": "https://registry.npmjs.org/bcrypt/-/bcrypt-0.7.8.tgz",
-      "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-0.7.8.tgz",
+      "from": "bcrypt@0.7.x",
       "dependencies": {
         "bindings": {
           "version": "1.0.0",
-          "from": "https://registry.npmjs.org/bindings/-/bindings-1.0.0.tgz",
-          "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.0.0.tgz"
+          "from": "bindings@1.0.0"
         }
       }
     },
+    "chai": {
+      "version": "1.5.0",
+      "from": "chai@1.5.x",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-1.5.0.tgz"
+    },
     "colors": {
       "version": "0.6.2",
-      "from": "colors@0.6.2"
+      "from": "colors@0.6.x"
     },
     "commander": {
       "version": "1.2.0",
-      "from": "commander@1.2.0",
+      "from": "commander@1.2.x",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-1.2.0.tgz",
       "dependencies": {
         "keypress": {
           "version": "0.1.0",
-          "from": "keypress@0.1.0"
+          "from": "keypress@0.1.x"
         }
       }
     },
     "congruence": {
       "version": "1.2.9",
-      "from": "congruence@1.2.9",
+      "from": "congruence@~1.2.4",
       "dependencies": {
         "moment": {
           "version": "2.5.1",
     },
     "connect-ensure-login": {
       "version": "0.1.1",
-      "from": "connect-ensure-login@0.1.1"
+      "from": "connect-ensure-login@0.1.x"
+    },
+    "csslint": {
+      "version": "0.10.0",
+      "from": "csslint@~0.10.0",
+      "resolved": "https://registry.npmjs.org/csslint/-/csslint-0.10.0.tgz",
+      "dependencies": {
+        "parserlib": {
+          "version": "0.2.5",
+          "from": "parserlib@~0.2.2"
+        }
+      }
     },
     "ejs": {
       "version": "0.8.8",
-      "from": "ejs@0.8.8"
+      "from": "ejs@0.8.x"
     },
     "express": {
       "version": "3.1.2",
-      "from": "express@3.1.2",
+      "from": "express@3.1.x",
+      "resolved": "https://registry.npmjs.org/express/-/express-3.1.2.tgz",
       "dependencies": {
         "connect": {
           "version": "2.7.5",
           "from": "connect@2.7.5",
+          "resolved": "https://registry.npmjs.org/connect/-/connect-2.7.5.tgz",
           "dependencies": {
             "qs": {
               "version": "0.5.1",
-              "from": "qs@0.5.1"
+              "from": "qs@0.5.1",
+              "resolved": "https://registry.npmjs.org/qs/-/qs-0.5.1.tgz"
             },
             "formidable": {
               "version": "1.0.11",
-              "from": "https://registry.npmjs.org/formidable/-/formidable-1.0.11.tgz",
+              "from": "formidable@1.0.11",
               "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.11.tgz"
             },
             "buffer-crc32": {
         },
         "mkdirp": {
           "version": "0.3.5",
-          "from": "mkdirp@0.3.5"
+          "from": "mkdirp@~0.3.4"
         },
         "cookie": {
           "version": "0.0.5",
-          "from": "cookie@0.0.5"
+          "from": "cookie@0.0.5",
+          "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.0.5.tgz"
         },
         "buffer-crc32": {
-          "version": "0.2.1",
-          "from": "buffer-crc32@0.2.1"
+          "version": "0.2.3",
+          "from": "buffer-crc32@~0.2.1",
+          "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.3.tgz"
         },
         "fresh": {
           "version": "0.1.0",
         },
         "methods": {
           "version": "0.0.1",
-          "from": "methods@0.0.1"
+          "from": "methods@0.0.1",
+          "resolved": "https://registry.npmjs.org/methods/-/methods-0.0.1.tgz"
         },
         "send": {
           "version": "0.1.0",
-          "from": "https://registry.npmjs.org/send/-/send-0.1.0.tgz",
+          "from": "send@0.1.0",
           "resolved": "https://registry.npmjs.org/send/-/send-0.1.0.tgz",
           "dependencies": {
             "mime": {
               "version": "1.2.6",
-              "from": "https://registry.npmjs.org/mime/-/mime-1.2.6.tgz",
+              "from": "mime@1.2.6",
               "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.6.tgz"
             }
           }
         },
         "cookie-signature": {
           "version": "1.0.0",
-          "from": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.0.tgz",
+          "from": "cookie-signature@1.0.0",
           "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.0.tgz"
         },
         "debug": {
-          "version": "0.8.1",
-          "from": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz"
+          "version": "1.0.4",
+          "from": "debug@*",
+          "dependencies": {
+            "ms": {
+              "version": "0.6.2",
+              "from": "ms@0.6.2"
+            }
+          }
         }
       }
     },
     "fluentreports": {
       "version": "0.0.2",
-      "from": "fluentreports@git://github.com/xtuple/fluentreports.git#161ecebe081ade6fdd56c1fd11471c39297f8d29",
+      "from": "fluentreports@git://github.com/xtuple/fluentreports.git",
       "resolved": "git://github.com/xtuple/fluentreports.git#161ecebe081ade6fdd56c1fd11471c39297f8d29",
       "dependencies": {
         "pdfkit": {
           "version": "0.2.6",
-          "from": "pdfkit@git://github.com/Nathanaela/pdfkit.git#5e393ce15484afc47b35edbca79f6d518cbce67c",
+          "from": "pdfkit@git://github.com/Nathanaela/pdfkit.git#Release",
           "resolved": "git://github.com/Nathanaela/pdfkit.git#5e393ce15484afc47b35edbca79f6d518cbce67c",
           "dependencies": {
             "png-js": {
               "version": "0.1.1",
-              "from": "png-js@0.1.1"
-            }
-          }
-        }
-      }
-    },
-    "ipp": {
-      "version": "0.0.5",
-      "from": "https://registry.npmjs.org/ipp/-/ipp-0.0.5.tgz",
-      "resolved": "https://registry.npmjs.org/ipp/-/ipp-0.0.5.tgz"
-    },
-    "json-patch": {
-      "version": "0.0.1",
-      "from": "json-patch@git://github.com/xtuple/JSON-Patch.git#eb69a78f6d041b2f630a9747a5b227c42c8df077",
-      "resolved": "git://github.com/xtuple/JSON-Patch.git#eb69a78f6d041b2f630a9747a5b227c42c8df077"
-    },
-    "less": {
-      "version": "1.5.0",
-      "from": "https://registry.npmjs.org/less/-/less-1.5.0.tgz",
-      "resolved": "https://registry.npmjs.org/less/-/less-1.5.0.tgz",
-      "dependencies": {
-        "mime": {
-          "version": "1.2.11",
-          "from": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
-          "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
-        },
-        "mkdirp": {
-          "version": "0.3.5",
-          "from": "mkdirp@0.3.5"
-        },
-        "clean-css": {
-          "version": "1.0.12",
-          "from": "clean-css@1.0.12",
-          "dependencies": {
-            "commander": {
-              "version": "1.3.2",
-              "from": "commander@1.3.2",
-              "dependencies": {
-                "keypress": {
-                  "version": "0.1.0",
-                  "from": "keypress@0.1.0"
-                }
-              }
-            }
-          }
-        },
-        "source-map": {
-          "version": "0.1.33",
-          "from": "source-map@0.1.33",
-          "dependencies": {
-            "amdefine": {
-              "version": "0.1.0",
-              "from": "amdefine@0.1.0"
-            }
-          }
-        }
-      }
-    },
-    "moment": {
-      "version": "2.4.0",
-      "from": "moment@2.4.0"
-    },
-    "nodemailer": {
-      "version": "0.3.44",
-      "from": "nodemailer@0.3.44",
-      "dependencies": {
-        "mailcomposer": {
-          "version": "0.2.9",
-          "from": "mailcomposer@0.2.9",
-          "dependencies": {
-            "mimelib": {
-              "version": "0.2.14",
-              "from": "mimelib@0.2.14",
-              "dependencies": {
-                "encoding": {
-                  "version": "0.1.7",
-                  "from": "encoding@0.1.7",
-                  "dependencies": {
-                    "iconv-lite": {
-                      "version": "0.2.11",
-                      "from": "iconv-lite@0.2.11"
-                    }
-                  }
-                },
-                "addressparser": {
-                  "version": "0.2.1",
-                  "from": "addressparser@0.2.1"
-                }
-              }
-            },
-            "mime": {
-              "version": "1.2.11",
-              "from": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
-              "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
-            },
-            "he": {
-              "version": "0.3.6",
-              "from": "he@0.3.6"
-            },
-            "punycode": {
-              "version": "1.2.4",
-              "from": "punycode@1.2.4"
-            },
-            "follow-redirects": {
-              "version": "0.0.3",
-              "from": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.3.tgz",
-              "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.3.tgz"
-            },
-            "dkim-signer": {
-              "version": "0.1.0",
-              "from": "dkim-signer@0.1.0"
-            }
-          }
-        },
-        "simplesmtp": {
-          "version": "0.3.29",
-          "from": "https://registry.npmjs.org/simplesmtp/-/simplesmtp-0.3.29.tgz",
-          "resolved": "https://registry.npmjs.org/simplesmtp/-/simplesmtp-0.3.29.tgz",
-          "dependencies": {
-            "rai": {
-              "version": "0.1.10",
-              "from": "https://registry.npmjs.org/rai/-/rai-0.1.10.tgz",
-              "resolved": "https://registry.npmjs.org/rai/-/rai-0.1.10.tgz"
-            },
-            "xoauth2": {
-              "version": "0.1.8",
-              "from": "xoauth2@0.1.8"
-            }
-          }
-        },
-        "optimist": {
-          "version": "0.6.1",
-          "from": "optimist@0.6.1",
-          "dependencies": {
-            "wordwrap": {
-              "version": "0.0.2",
-              "from": "wordwrap@0.0.2"
-            },
-            "minimist": {
-              "version": "0.0.9",
-              "from": "https://registry.npmjs.org/minimist/-/minimist-0.0.9.tgz",
-              "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.9.tgz"
+              "from": "png-js@>=0.1.0"
             }
           }
         }
       }
     },
-    "npm": {
-      "version": "1.2.30",
-      "from": "https://registry.npmjs.org/npm/-/npm-1.2.30.tgz",
-      "resolved": "https://registry.npmjs.org/npm/-/npm-1.2.30.tgz",
+    "googleapis": {
+      "version": "0.4.7",
+      "from": "googleapis@~0.4.6",
+      "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-0.4.7.tgz",
       "dependencies": {
-        "semver": {
-          "version": "1.1.4",
-          "from": "semver@1.1.4"
-        },
-        "ini": {
-          "version": "1.1.0",
-          "from": "ini@latest"
-        },
-        "slide": {
-          "version": "1.1.4",
-          "from": "slide@latest"
-        },
-        "abbrev": {
-          "version": "1.0.4",
-          "from": "abbrev@latest"
-        },
-        "graceful-fs": {
-          "version": "1.2.2",
-          "from": "graceful-fs@latest"
-        },
-        "minimatch": {
-          "version": "0.2.12",
-          "from": "minimatch@latest",
-          "dependencies": {
-            "sigmund": {
-              "version": "1.0.0",
-              "from": "sigmund@~1.0.0",
-              "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz"
-            }
-          }
-        },
-        "nopt": {
-          "version": "2.1.1",
-          "from": "nopt@latest"
-        },
-        "rimraf": {
-          "version": "2.1.4",
-          "from": "rimraf@2"
-        },
         "request": {
-          "version": "2.21.0",
-          "from": "request@latest",
+          "version": "2.25.0",
+          "from": "request@~2.25.0",
           "dependencies": {
             "qs": {
-              "version": "0.6.5",
+              "version": "0.6.6",
               "from": "qs@~0.6.0"
             },
             "json-stringify-safe": {
-              "version": "4.0.0",
-              "from": "json-stringify-safe@~4.0.0"
+              "version": "5.0.0",
+              "from": "json-stringify-safe@~5.0.0"
             },
             "forever-agent": {
-              "version": "0.5.0",
+              "version": "0.5.2",
               "from": "forever-agent@~0.5.0"
             },
             "tunnel-agent": {
               "from": "tunnel-agent@~0.3.0"
             },
             "http-signature": {
-              "version": "0.9.11",
-              "from": "http-signature@~0.9.11",
+              "version": "0.10.0",
+              "from": "http-signature@~0.10.0",
               "dependencies": {
                 "assert-plus": {
                   "version": "0.1.2",
-                  "from": "assert-plus@0.1.2"
+                  "from": "assert-plus@0.1.2",
+                  "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz"
                 },
                 "asn1": {
                   "version": "0.1.11",
-                  "from": "asn1@0.1.11"
+                  "from": "asn1@0.1.11",
+                  "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
                 },
                 "ctype": {
                   "version": "0.5.2",
               }
             },
             "hawk": {
-              "version": "0.13.1",
-              "from": "hawk@~0.13.0",
+              "version": "1.0.0",
+              "from": "hawk@~1.0.0",
               "dependencies": {
                 "hoek": {
-                  "version": "0.8.5",
-                  "from": "hoek@0.8.x"
+                  "version": "0.9.1",
+                  "from": "hoek@0.9.x"
                 },
                 "boom": {
                   "version": "0.4.2",
-                  "from": "boom@0.4.x",
-                  "dependencies": {
-                    "hoek": {
-                      "version": "0.9.1",
-                      "from": "hoek@0.9.x",
-                      "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
-                    }
-                  }
+                  "from": "boom@0.4.x"
                 },
                 "cryptiles": {
-                  "version": "0.2.1",
+                  "version": "0.2.2",
                   "from": "cryptiles@0.2.x"
                 },
                 "sntp": {
                   "version": "0.2.4",
-                  "from": "sntp@0.2.x",
-                  "dependencies": {
-                    "hoek": {
-                      "version": "0.9.1",
-                      "from": "hoek@0.9.x",
-                      "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
-                    }
-                  }
+                  "from": "sntp@0.2.x"
                 }
               }
             },
               "from": "cookie-jar@~0.3.0"
             },
             "node-uuid": {
-              "version": "1.4.0",
+              "version": "1.4.1",
               "from": "node-uuid@~1.4.0"
             },
             "mime": {
-              "version": "1.2.9",
+              "version": "1.2.11",
               "from": "mime@~1.2.9"
             },
             "form-data": {
-              "version": "0.0.8",
-              "from": "form-data@0.0.8",
+              "version": "0.1.4",
+              "from": "form-data@~0.1.0",
+              "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz",
               "dependencies": {
                 "combined-stream": {
-                  "version": "0.0.4",
+                  "version": "0.0.5",
                   "from": "combined-stream@~0.0.4",
+                  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.5.tgz",
                   "dependencies": {
                     "delayed-stream": {
                       "version": "0.0.5",
-                      "from": "delayed-stream@0.0.5"
+                      "from": "delayed-stream@0.0.5",
+                      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
                     }
                   }
                 },
                 "async": {
-                  "version": "0.2.9",
-                  "from": "async@~0.2.7"
+                  "version": "0.9.0",
+                  "from": "async@~0.9.0"
                 }
               }
             }
           }
         },
-        "which": {
-          "version": "1.0.5",
-          "from": "which@1"
-        },
-        "tar": {
-          "version": "0.1.17",
-          "from": "tar@0.1.17",
-          "resolved": "https://registry.npmjs.org/tar/-/tar-0.1.17.tgz"
-        },
-        "fstream": {
-          "version": "0.1.22",
-          "from": "fstream@latest"
-        },
-        "block-stream": {
-          "version": "0.0.6",
-          "from": "block-stream@*"
-        },
-        "inherits": {
-          "version": "1.0.0",
-          "from": "git://github.com/isaacs/inherits"
-        },
-        "mkdirp": {
-          "version": "0.3.5",
-          "from": "mkdirp@0.3.5",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
-        },
-        "read": {
-          "version": "1.0.4",
-          "from": "read@~1.0.3",
-          "dependencies": {
-            "mute-stream": {
-              "version": "0.0.3",
-              "from": "mute-stream@~0.0.2"
-            }
-          }
-        },
-        "lru-cache": {
-          "version": "2.3.0",
-          "from": "lru-cache@latest"
-        },
-        "node-gyp": {
-          "version": "0.10.0",
-          "from": "node-gyp@latest",
-          "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-0.10.0.tgz"
-        },
-        "fstream-npm": {
-          "version": "0.1.4",
-          "from": "fstream-npm@latest",
-          "dependencies": {
-            "fstream-ignore": {
-              "version": "0.0.6",
-              "from": "fstream-ignore@~0.0.5"
-            }
-          }
-        },
-        "uid-number": {
-          "version": "0.0.3",
-          "from": "../uid-number"
-        },
-        "archy": {
-          "version": "0.0.2",
-          "from": "archy@0.0.2"
-        },
-        "chownr": {
-          "version": "0.0.1",
-          "from": "../chownr"
-        },
-        "npmlog": {
-          "version": "0.0.2",
-          "from": "npmlog@0"
-        },
-        "ansi": {
-          "version": "0.1.2",
-          "from": "ansi@~0.1.2"
+        "async": {
+          "version": "0.2.6",
+          "from": "async@0.2.6",
+          "resolved": "https://registry.npmjs.org/async/-/async-0.2.6.tgz"
         },
-        "npm-registry-client": {
-          "version": "0.2.24",
-          "from": "npm-registry-client@~0.2.22",
+        "gapitoken": {
+          "version": "0.1.0",
+          "from": "gapitoken@0.1.0",
+          "resolved": "https://registry.npmjs.org/gapitoken/-/gapitoken-0.1.0.tgz",
           "dependencies": {
-            "couch-login": {
-              "version": "0.1.17",
-              "from": "couch-login@"
-            }
-          }
-        },
-        "read-package-json": {
-          "version": "0.4.1",
-          "from": "read-package-json@~0.4.1",
+            "jws": {
+              "version": "0.0.2",
+              "from": "jws@0.0.2",
+              "resolved": "https://registry.npmjs.org/jws/-/jws-0.0.2.tgz",
+              "dependencies": {
+                "tap": {
+                  "version": "0.3.3",
+                  "from": "tap@~0.3.3",
+                  "dependencies": {
+                    "inherits": {
+                      "version": "1.0.0"
+                    },
+                    "yamlish": {
+                      "version": "0.0.5"
+                    },
+                    "slide": {
+                      "version": "1.1.5",
+                      "from": "slide@*"
+                    },
+                    "runforcover": {
+                      "version": "0.0.2",
+                      "from": "runforcover@~0.0.2",
+                      "dependencies": {
+                        "bunker": {
+                          "version": "0.1.2",
+                          "from": "bunker@0.1.X",
+                          "dependencies": {
+                            "burrito": {
+                              "version": "0.2.12",
+                              "from": "burrito@>=0.2.5 <0.3",
+                              "dependencies": {
+                                "traverse": {
+                                  "version": "0.5.2",
+                                  "from": "traverse@~0.5.1"
+                                },
+                                "uglify-js": {
+                                  "version": "1.1.1",
+                                  "from": "uglify-js@~1.1.1",
+                                  "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.1.1.tgz"
+                                }
+                              }
+                            }
+                          }
+                        }
+                      }
+                    },
+                    "nopt": {
+                      "version": "2.2.1",
+                      "from": "nopt@~2",
+                      "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.2.1.tgz",
+                      "dependencies": {
+                        "abbrev": {
+                          "version": "1.0.5",
+                          "from": "abbrev@1",
+                          "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz"
+                        }
+                      }
+                    },
+                    "mkdirp": {
+                      "version": "0.3.5",
+                      "from": "mkdirp@~0.3"
+                    },
+                    "difflet": {
+                      "version": "0.2.6",
+                      "from": "difflet@~0.2.0",
+                      "dependencies": {
+                        "traverse": {
+                          "version": "0.6.6",
+                          "from": "traverse@0.6.x"
+                        },
+                        "charm": {
+                          "version": "0.1.2",
+                          "from": "charm@0.1.x"
+                        },
+                        "deep-is": {
+                          "version": "0.1.3",
+                          "from": "deep-is@0.1.x",
+                          "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
+                        }
+                      }
+                    },
+                    "deep-equal": {
+                      "version": "0.0.0",
+                      "from": "deep-equal@~0.0.0"
+                    },
+                    "buffer-equal": {
+                      "version": "0.0.1",
+                      "from": "buffer-equal@~0.0.0"
+                    }
+                  }
+                },
+                "base64url": {
+                  "version": "0.0.3",
+                  "from": "base64url@0.0.3",
+                  "resolved": "https://registry.npmjs.org/base64url/-/base64url-0.0.3.tgz"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "html5": {
+      "version": "0.3.13",
+      "from": "html5@0.3.13",
+      "resolved": "https://registry.npmjs.org/html5/-/html5-0.3.13.tgz",
+      "dependencies": {
+        "jsdom": {
+          "version": "1.0.0-pre.3",
+          "from": "jsdom@>= 0.6.0",
+          "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-1.0.0-pre.3.tgz",
           "dependencies": {
-            "normalize-package-data": {
-              "version": "0.1.6",
-              "from": "normalize-package-data@~0.1.2",
+            "htmlparser2": {
+              "version": "3.7.3",
+              "from": "htmlparser2@>= 3.1.5 <4",
+              "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.7.3.tgz",
               "dependencies": {
-                "github-url-from-git": {
+                "domhandler": {
+                  "version": "2.2.0",
+                  "from": "domhandler@2.2"
+                },
+                "domutils": {
+                  "version": "1.5.0",
+                  "from": "domutils@1.5"
+                },
+                "domelementtype": {
                   "version": "1.1.1",
-                  "from": "github-url-from-git@~1.1.1"
+                  "from": "domelementtype@1"
+                },
+                "readable-stream": {
+                  "version": "1.1.13",
+                  "from": "readable-stream@1.1",
+                  "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz",
+                  "dependencies": {
+                    "core-util-is": {
+                      "version": "1.0.1",
+                      "from": "core-util-is@~1.0.0"
+                    },
+                    "isarray": {
+                      "version": "0.0.1",
+                      "from": "isarray@0.0.1"
+                    },
+                    "string_decoder": {
+                      "version": "0.10.31",
+                      "from": "string_decoder@~0.10.x",
+                      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+                    },
+                    "inherits": {
+                      "version": "2.0.1",
+                      "from": "inherits@~2.0.1"
+                    }
+                  }
+                },
+                "entities": {
+                  "version": "1.0.0",
+                  "from": "entities@1.0"
+                }
+              }
+            },
+            "parse5": {
+              "version": "1.0.1",
+              "from": "parse5@~1.0.1",
+              "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.0.1.tgz"
+            },
+            "nwmatcher": {
+              "version": "1.3.3",
+              "from": "nwmatcher@~1.3.2"
+            },
+            "xmlhttprequest": {
+              "version": "1.6.0",
+              "from": "xmlhttprequest@>=1.5.0"
+            },
+            "cssom": {
+              "version": "0.3.0",
+              "from": "cssom@~0.3.0"
+            },
+            "cssstyle": {
+              "version": "0.2.14",
+              "from": "cssstyle@~0.2.9"
+            },
+            "contextify": {
+              "version": "0.1.8",
+              "from": "contextify@~0.1.5",
+              "dependencies": {
+                "bindings": {
+                  "version": "1.2.1",
+                  "from": "bindings@*",
+                  "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
+                },
+                "nan": {
+                  "version": "1.0.0",
+                  "from": "nan@~1.0.0"
                 }
               }
             }
           }
         },
-        "read-installed": {
-          "version": "0.1.1",
-          "from": "read-installed@0"
+        "opts": {
+          "version": "1.2.2",
+          "from": "opts@~1.2.1"
         },
-        "glob": {
-          "version": "3.2.1",
-          "from": "glob@3.2.1",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.1.tgz"
+        "html5-entities": {
+          "version": "0.5.1",
+          "from": "html5-entities@~0.5.0",
+          "resolved": "https://registry.npmjs.org/html5-entities/-/html5-entities-0.5.1.tgz"
+        }
+      }
+    },
+    "ipp": {
+      "version": "0.0.5",
+      "from": "ipp@0.0.5"
+    },
+    "jquery": {
+      "version": "2.1.1",
+      "from": "jquery@~2.1.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.1.1.tgz"
+    },
+    "jshint": {
+      "version": "2.4.4",
+      "from": "jshint@2.4.x",
+      "dependencies": {
+        "shelljs": {
+          "version": "0.1.4",
+          "from": "shelljs@0.1.x"
         },
-        "init-package-json": {
-          "version": "0.0.8",
-          "from": "init-package-json@latest",
+        "cli": {
+          "version": "0.4.5",
+          "from": "cli@0.4.x",
           "dependencies": {
-            "promzard": {
-              "version": "0.2.0",
-              "from": "promzard@~0.2.0"
+            "glob": {
+              "version": "4.0.5",
+              "from": "glob@>= 3.1.4",
+              "resolved": "https://registry.npmjs.org/glob/-/glob-4.0.5.tgz",
+              "dependencies": {
+                "inherits": {
+                  "version": "2.0.1",
+                  "from": "inherits@2"
+                },
+                "minimatch": {
+                  "version": "1.0.0",
+                  "from": "minimatch@^1.0.0",
+                  "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz",
+                  "dependencies": {
+                    "lru-cache": {
+                      "version": "2.5.0",
+                      "from": "lru-cache@2"
+                    },
+                    "sigmund": {
+                      "version": "1.0.0",
+                      "from": "sigmund@~1.0.0"
+                    }
+                  }
+                },
+                "once": {
+                  "version": "1.3.0",
+                  "from": "once@^1.3.0",
+                  "resolved": "https://registry.npmjs.org/once/-/once-1.3.0.tgz"
+                },
+                "graceful-fs": {
+                  "version": "3.0.2",
+                  "from": "graceful-fs@^3.0.2",
+                  "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.2.tgz"
+                }
+              }
             }
           }
         },
-        "osenv": {
-          "version": "0.0.3",
-          "from": "osenv@latest"
-        },
-        "lockfile": {
-          "version": "0.3.4",
-          "from": "lockfile@0.3.4",
-          "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-0.3.4.tgz"
-        },
-        "retry": {
-          "version": "0.6.0",
-          "from": "retry"
-        },
-        "once": {
-          "version": "1.1.1",
-          "from": "once"
+        "minimatch": {
+          "version": "0.4.0",
+          "from": "minimatch@0.x.x",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.4.0.tgz",
+          "dependencies": {
+            "lru-cache": {
+              "version": "2.5.0",
+              "from": "lru-cache@2"
+            },
+            "sigmund": {
+              "version": "1.0.0",
+              "from": "sigmund@~1.0.0"
+            }
+          }
         },
-        "npmconf": {
-          "version": "0.1.0",
-          "from": "npmconf@latest",
+        "htmlparser2": {
+          "version": "3.3.0",
+          "from": "htmlparser2@3.3.x",
           "dependencies": {
-            "config-chain": {
-              "version": "1.1.7",
-              "from": "config-chain@~1.1.1",
+            "domhandler": {
+              "version": "2.1.0",
+              "from": "domhandler@2.1"
+            },
+            "domutils": {
+              "version": "1.1.6",
+              "from": "domutils@1.1"
+            },
+            "domelementtype": {
+              "version": "1.1.1",
+              "from": "domelementtype@1"
+            },
+            "readable-stream": {
+              "version": "1.0.31",
+              "from": "readable-stream@1.0",
+              "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.31.tgz",
               "dependencies": {
-                "proto-list": {
-                  "version": "1.2.2",
-                  "from": "proto-list@~1.2.1"
+                "core-util-is": {
+                  "version": "1.0.1",
+                  "from": "core-util-is@~1.0.0"
+                },
+                "isarray": {
+                  "version": "0.0.1",
+                  "from": "isarray@0.0.1"
+                },
+                "string_decoder": {
+                  "version": "0.10.31",
+                  "from": "string_decoder@~0.10.x",
+                  "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+                },
+                "inherits": {
+                  "version": "2.0.1",
+                  "from": "inherits@~2.0.1"
                 }
               }
             }
           }
         },
-        "opener": {
-          "version": "1.3.0",
-          "from": "opener@latest"
-        },
-        "chmodr": {
-          "version": "0.1.0",
-          "from": "chmodr@latest"
+        "console-browserify": {
+          "version": "0.1.6",
+          "from": "console-browserify@0.1.x"
         },
-        "cmd-shim": {
-          "version": "1.1.0",
-          "from": "cmd-shim@"
-        },
-        "sha": {
-          "version": "1.0.1",
-          "from": "sha@~1.0.1"
-        },
-        "editor": {
-          "version": "0.0.4",
-          "from": "editor@"
-        },
-        "child-process-close": {
-          "version": "0.1.1",
-          "from": "child-process-close@",
-          "resolved": "https://registry.npmjs.org/child-process-close/-/child-process-close-0.1.1.tgz"
-        },
-        "npm-user-validate": {
-          "version": "0.0.1",
-          "from": "npm-user-validate@0"
-        }
-      }
-    },
-    "node-forge": {
-      "version": "0.6.2",
-      "from": "node-forge@0.6.2"
-    },
-    "oauth2orize": {
-      "version": "0.1.0",
-      "from": "oauth2orize@0.1.0",
-      "dependencies": {
-        "debug": {
-          "version": "0.7.4",
-          "from": "debug@0.7.4"
+        "exit": {
+          "version": "0.1.2",
+          "from": "exit@0.1.x"
         }
       }
     },
-    "oauth2orize-jwt-bearer": {
-      "version": "0.1.0",
-      "from": "oauth2orize-jwt-bearer@0.1.0",
-      "dependencies": {
-        "pkginfo": {
-          "version": "0.2.3",
-          "from": "pkginfo@0.2.3"
-        }
-      }
+    "json-patch": {
+      "version": "0.0.1",
+      "from": "json-patch@git://github.com/xtuple/JSON-Patch.git",
+      "resolved": "git://github.com/xtuple/JSON-Patch.git#eb69a78f6d041b2f630a9747a5b227c42c8df077"
     },
-    "passport": {
-      "version": "0.1.18",
-      "from": "passport@0.1.18",
+    "less": {
+      "version": "1.5.0",
+      "from": "less@1.5.0",
+      "resolved": "https://registry.npmjs.org/less/-/less-1.5.0.tgz",
       "dependencies": {
-        "pkginfo": {
-          "version": "0.2.3",
-          "from": "pkginfo@0.2.3"
+        "mime": {
+          "version": "1.2.11",
+          "from": "mime@~1.2.7"
         },
-        "pause": {
-          "version": "0.0.1",
-          "from": "pause@0.0.1"
-        }
-      }
-    },
-    "passport-http": {
-      "version": "0.2.2",
-      "from": "passport-http@0.2.2",
-      "dependencies": {
-        "pkginfo": {
-          "version": "0.2.3",
-          "from": "pkginfo@0.2.3"
+        "mkdirp": {
+          "version": "0.3.5",
+          "from": "mkdirp@~0.3.4"
+        },
+        "clean-css": {
+          "version": "1.0.12",
+          "from": "clean-css@1.0.x",
+          "dependencies": {
+            "commander": {
+              "version": "1.3.2",
+              "from": "commander@1.3.x",
+              "dependencies": {
+                "keypress": {
+                  "version": "0.1.0",
+                  "from": "keypress@0.1.x"
+                }
+              }
+            }
+          }
+        },
+        "source-map": {
+          "version": "0.1.38",
+          "from": "source-map@0.1.x",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.38.tgz",
+          "dependencies": {
+            "amdefine": {
+              "version": "0.1.0",
+              "from": "amdefine@>=0.0.4"
+            }
+          }
         }
       }
     },
-    "passport-http-bearer": {
-      "version": "0.2.1",
-      "from": "passport-http-bearer@0.2.1",
+    "mocha": {
+      "version": "1.9.0",
+      "from": "mocha@1.9.x",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-1.9.0.tgz",
       "dependencies": {
-        "pkginfo": {
-          "version": "0.2.3",
-          "from": "pkginfo@0.2.3"
+        "commander": {
+          "version": "0.6.1",
+          "from": "commander@0.6.1"
+        },
+        "growl": {
+          "version": "1.7.0",
+          "from": "growl@1.7.x"
+        },
+        "jade": {
+          "version": "0.26.3",
+          "from": "jade@0.26.3",
+          "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz",
+          "dependencies": {
+            "mkdirp": {
+              "version": "0.3.0",
+              "from": "mkdirp@0.3.0"
+            }
+          }
+        },
+        "diff": {
+          "version": "1.0.2",
+          "from": "diff@1.0.2"
+        },
+        "debug": {
+          "version": "1.0.4",
+          "from": "debug@*",
+          "dependencies": {
+            "ms": {
+              "version": "0.6.2",
+              "from": "ms@0.6.2"
+            }
+          }
+        },
+        "mkdirp": {
+          "version": "0.3.3",
+          "from": "mkdirp@0.3.3"
+        },
+        "ms": {
+          "version": "0.3.0",
+          "from": "ms@0.3.0"
         }
       }
     },
-    "passport-local": {
-      "version": "0.1.6",
-      "from": "passport-local@0.1.6",
-      "dependencies": {
-        "pkginfo": {
-          "version": "0.2.3",
-          "from": "pkginfo@0.2.3"
-        }
-      }
+    "moment": {
+      "version": "2.4.0",
+      "from": "moment@2.4.x",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.4.0.tgz"
     },
-    "passport-oauth2-client-password": {
-      "version": "0.1.1",
-      "from": "passport-oauth2-client-password@0.1.1",
-      "dependencies": {
-        "pkginfo": {
-          "version": "0.2.3",
-          "from": "pkginfo@0.2.3"
-        }
-      }
+    "node-forge": {
+      "version": "0.6.12",
+      "from": "node-forge@0.6.x",
+      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.6.12.tgz"
     },
-    "passport-oauth2-jwt-bearer": {
-      "version": "0.1.1",
-      "from": "passport-oauth2-jwt-bearer@0.1.1",
+    "nodemailer": {
+      "version": "0.3.44",
+      "from": "nodemailer@0.3.x",
+      "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-0.3.44.tgz",
       "dependencies": {
-        "pkginfo": {
-          "version": "0.2.3",
-          "from": "pkginfo@0.2.3"
+        "mailcomposer": {
+          "version": "0.2.12",
+          "from": "mailcomposer@>= 0.1.29",
+          "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-0.2.12.tgz",
+          "dependencies": {
+            "mimelib": {
+              "version": "0.2.17",
+              "from": "mimelib@~0.2.15",
+              "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.2.17.tgz",
+              "dependencies": {
+                "encoding": {
+                  "version": "0.1.8",
+                  "from": "encoding@~0.1.7",
+                  "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.8.tgz",
+                  "dependencies": {
+                    "iconv-lite": {
+                      "version": "0.4.4",
+                      "from": "iconv-lite@~0.4.3",
+                      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.4.tgz"
+                    }
+                  }
+                },
+                "addressparser": {
+                  "version": "0.2.1",
+                  "from": "addressparser@~0.2.1"
+                }
+              }
+            },
+            "mime": {
+              "version": "1.2.11",
+              "from": "mime@1.2.x"
+            },
+            "he": {
+              "version": "0.3.6",
+              "from": "he@~0.3.6"
+            },
+            "follow-redirects": {
+              "version": "0.0.3",
+              "from": "follow-redirects@0.0.3",
+              "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.3.tgz"
+            },
+            "dkim-signer": {
+              "version": "0.1.2",
+              "from": "dkim-signer@~0.1.1",
+              "dependencies": {
+                "punycode": {
+                  "version": "1.2.4",
+                  "from": "punycode@~1.2.4"
+                }
+              }
+            }
+          }
+        },
+        "simplesmtp": {
+          "version": "0.3.32",
+          "from": "simplesmtp@>= 0.1.28",
+          "dependencies": {
+            "rai": {
+              "version": "0.1.11",
+              "from": "rai@~0.1.11"
+            },
+            "xoauth2": {
+              "version": "0.1.8",
+              "from": "xoauth2@~0.1.8"
+            }
+          }
+        },
+        "optimist": {
+          "version": "0.6.1",
+          "from": "optimist@*",
+          "dependencies": {
+            "wordwrap": {
+              "version": "0.0.2",
+              "from": "wordwrap@~0.0.2"
+            },
+            "minimist": {
+              "version": "0.0.10",
+              "from": "minimist@~0.0.1"
+            }
+          }
         }
       }
     },
-    "paynode": {
-      "version": "0.3.6",
-      "from": "https://registry.npmjs.org/paynode/-/paynode-0.3.6.tgz",
-      "resolved": "https://registry.npmjs.org/paynode/-/paynode-0.3.6.tgz",
+    "nodemon": {
+      "version": "1.0.20",
+      "from": "nodemon@~1.0.15",
       "dependencies": {
-        "braintree": {
-          "version": "1.14.0",
-          "from": "braintree@1.14.0",
+        "update-notifier": {
+          "version": "0.1.10",
+          "from": "update-notifier@~0.1.8",
           "dependencies": {
-            "dateformat": {
-              "version": "1.0.1-1.2.3",
-              "from": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.1-1.2.3.tgz",
-              "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.1-1.2.3.tgz"
-            },
-            "semver": {
-              "version": "2.2.1",
-              "from": "https://registry.npmjs.org/semver/-/semver-2.2.1.tgz",
-              "resolved": "https://registry.npmjs.org/semver/-/semver-2.2.1.tgz"
+            "chalk": {
+              "version": "0.4.0",
+              "from": "chalk@^0.4.0",
+              "dependencies": {
+                "has-color": {
+                  "version": "0.1.7",
+                  "from": "has-color@~0.1.0"
+                },
+                "ansi-styles": {
+                  "version": "1.0.0",
+                  "from": "ansi-styles@~1.0.0"
+                },
+                "strip-ansi": {
+                  "version": "0.1.1",
+                  "from": "strip-ansi@~0.1.0"
+                }
+              }
             },
-            "readable-stream": {
-              "version": "1.1.10",
-              "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.10.tgz",
-              "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.10.tgz",
+            "configstore": {
+              "version": "0.3.1",
+              "from": "configstore@^0.3.0",
+              "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.1.tgz",
               "dependencies": {
-                "core-util-is": {
-                  "version": "1.0.1",
-                  "from": "core-util-is@1.0.1"
+                "graceful-fs": {
+                  "version": "3.0.2",
+                  "from": "graceful-fs@^3.0.2",
+                  "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.2.tgz"
+                },
+                "js-yaml": {
+                  "version": "3.0.2",
+                  "from": "js-yaml@~3.0.1",
+                  "dependencies": {
+                    "argparse": {
+                      "version": "0.1.15",
+                      "from": "argparse@~ 0.1.11"
+                    },
+                    "esprima": {
+                      "version": "1.0.4",
+                      "from": "esprima@~ 1.0.2"
+                    }
+                  }
+                },
+                "mkdirp": {
+                  "version": "0.5.0",
+                  "from": "mkdirp@~0.5.0",
+                  "dependencies": {
+                    "minimist": {
+                      "version": "0.0.8",
+                      "from": "minimist@0.0.8",
+                      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
+                    }
+                  }
+                },
+                "object-assign": {
+                  "version": "0.3.1",
+                  "from": "object-assign@~0.3.1",
+                  "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-0.3.1.tgz"
                 },
-                "string_decoder": {
-                  "version": "0.10.25-1",
-                  "from": "string_decoder@0.10.25-1"
+                "osenv": {
+                  "version": "0.1.0",
+                  "from": "osenv@~0.1.0",
+                  "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.0.tgz"
                 },
-                "debuglog": {
-                  "version": "0.0.2",
-                  "from": "https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz",
-                  "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz"
+                "uuid": {
+                  "version": "1.4.1",
+                  "from": "uuid@~1.4.1"
                 }
               }
             },
-            "underscore": {
-              "version": "1.3.1",
-              "from": "https://registry.npmjs.org/underscore/-/underscore-1.3.1.tgz",
-              "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.3.1.tgz"
-            },
-            "xml2js": {
-              "version": "0.1.13",
-              "from": "xml2js@0.1.13",
+            "request": {
+              "version": "2.40.0",
+              "from": "request@^2.36.0",
+              "resolved": "https://registry.npmjs.org/request/-/request-2.40.0.tgz",
               "dependencies": {
-                "sax": {
-                  "version": "0.6.0",
-                  "from": "sax@0.6.0"
+                "qs": {
+                  "version": "1.0.2",
+                  "from": "qs@~1.0.0",
+                  "resolved": "https://registry.npmjs.org/qs/-/qs-1.0.2.tgz"
+                },
+                "json-stringify-safe": {
+                  "version": "5.0.0",
+                  "from": "json-stringify-safe@~5.0.0"
+                },
+                "mime-types": {
+                  "version": "1.0.2",
+                  "from": "mime-types@~1.0.1",
+                  "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz"
+                },
+                "forever-agent": {
+                  "version": "0.5.2",
+                  "from": "forever-agent@~0.5.0"
+                },
+                "node-uuid": {
+                  "version": "1.4.1",
+                  "from": "node-uuid@~1.4.0"
+                },
+                "tough-cookie": {
+                  "version": "0.12.1",
+                  "from": "tough-cookie@>=0.12.0",
+                  "dependencies": {
+                    "punycode": {
+                      "version": "1.3.1",
+                      "from": "punycode@>=0.2.0",
+                      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.1.tgz"
+                    }
+                  }
+                },
+                "form-data": {
+                  "version": "0.1.4",
+                  "from": "form-data@~0.1.0",
+                  "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz",
+                  "dependencies": {
+                    "combined-stream": {
+                      "version": "0.0.5",
+                      "from": "combined-stream@~0.0.4",
+                      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.5.tgz",
+                      "dependencies": {
+                        "delayed-stream": {
+                          "version": "0.0.5",
+                          "from": "delayed-stream@0.0.5",
+                          "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
+                        }
+                      }
+                    },
+                    "mime": {
+                      "version": "1.2.11",
+                      "from": "mime@~1.2.11"
+                    },
+                    "async": {
+                      "version": "0.9.0",
+                      "from": "async@~0.9.0"
+                    }
+                  }
+                },
+                "tunnel-agent": {
+                  "version": "0.4.0",
+                  "from": "tunnel-agent@~0.4.0",
+                  "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.0.tgz"
+                },
+                "http-signature": {
+                  "version": "0.10.0",
+                  "from": "http-signature@~0.10.0",
+                  "dependencies": {
+                    "assert-plus": {
+                      "version": "0.1.2",
+                      "from": "assert-plus@0.1.2",
+                      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz"
+                    },
+                    "asn1": {
+                      "version": "0.1.11",
+                      "from": "asn1@0.1.11",
+                      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
+                    },
+                    "ctype": {
+                      "version": "0.5.2",
+                      "from": "ctype@0.5.2"
+                    }
+                  }
+                },
+                "oauth-sign": {
+                  "version": "0.3.0",
+                  "from": "oauth-sign@~0.3.0"
+                },
+                "hawk": {
+                  "version": "1.1.1",
+                  "from": "hawk@1.1.1",
+                  "dependencies": {
+                    "hoek": {
+                      "version": "0.9.1",
+                      "from": "hoek@0.9.x"
+                    },
+                    "boom": {
+                      "version": "0.4.2",
+                      "from": "boom@0.4.x"
+                    },
+                    "cryptiles": {
+                      "version": "0.2.2",
+                      "from": "cryptiles@0.2.x"
+                    },
+                    "sntp": {
+                      "version": "0.2.4",
+                      "from": "sntp@0.2.x"
+                    }
+                  }
+                },
+                "aws-sign2": {
+                  "version": "0.5.0",
+                  "from": "aws-sign2@~0.5.0"
+                },
+                "stringstream": {
+                  "version": "0.0.4",
+                  "from": "stringstream@~0.0.4",
+                  "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz"
                 }
               }
             },
-            "source-map-support": {
-              "version": "0.1.2",
-              "from": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.1.2.tgz",
-              "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.1.2.tgz",
+            "semver": {
+              "version": "2.3.2",
+              "from": "semver@^2.3.0",
+              "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz"
+            }
+          }
+        },
+        "minimatch": {
+          "version": "0.2.14",
+          "from": "minimatch@~0.2.14",
+          "dependencies": {
+            "lru-cache": {
+              "version": "2.5.0",
+              "from": "lru-cache@2"
+            },
+            "sigmund": {
+              "version": "1.0.0",
+              "from": "sigmund@~1.0.0"
+            }
+          }
+        },
+        "ps-tree": {
+          "version": "0.0.3",
+          "from": "ps-tree@0.0.3",
+          "dependencies": {
+            "event-stream": {
+              "version": "0.5.3",
+              "from": "event-stream@~0.5",
               "dependencies": {
-                "source-map": {
-                  "version": "0.1.8",
-                  "from": "https://registry.npmjs.org/source-map/-/source-map-0.1.8.tgz",
-                  "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.8.tgz",
+                "optimist": {
+                  "version": "0.2.8",
+                  "from": "optimist@0.2",
                   "dependencies": {
-                    "amdefine": {
-                      "version": "0.1.0",
-                      "from": "amdefine@0.1.0"
+                    "wordwrap": {
+                      "version": "0.0.2",
+                      "from": "wordwrap@>=0.0.1 <0.1.0"
                     }
                   }
                 }
         }
       }
     },
-    "pg": {
-      "version": "0.14.1",
-      "from": "pg@0.14.1",
+    "npm": {
+      "version": "1.4.24",
+      "from": "npm@1.4.x",
       "dependencies": {
-        "generic-pool": {
-          "version": "2.0.4",
-          "from": "generic-pool@2.0.4"
+        "abbrev": {
+          "version": "1.0.5",
+          "from": "abbrev@latest",
+          "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz"
         },
-        "deprecate": {
-          "version": "0.1.0",
-          "from": "deprecate@0.1.0"
-        }
-      }
-    },
-    "request": {
-      "version": "2.14.0",
-      "from": "request@2.14.0",
-      "dependencies": {
-        "form-data": {
+        "ansi": {
+          "version": "0.3.0",
+          "from": "ansi@latest",
+          "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.0.tgz"
+        },
+        "ansicolors": {
+          "version": "0.3.2",
+          "from": "ansicolors@latest"
+        },
+        "ansistyles": {
+          "version": "0.1.3",
+          "from": "ansistyles@0.1.3",
+          "resolved": "https://registry.npmjs.org/ansistyles/-/ansistyles-0.1.3.tgz"
+        },
+        "archy": {
+          "version": "0.0.2",
+          "from": "archy@0.0.2"
+        },
+        "block-stream": {
           "version": "0.0.7",
-          "from": "form-data@~0.0.3",
+          "from": "block-stream@latest"
+        },
+        "char-spinner": {
+          "version": "1.0.1",
+          "from": "char-spinner@latest",
+          "resolved": "https://registry.npmjs.org/char-spinner/-/char-spinner-1.0.1.tgz"
+        },
+        "child-process-close": {
+          "version": "0.1.1",
+          "from": "child-process-close@",
+          "resolved": "https://registry.npmjs.org/child-process-close/-/child-process-close-0.1.1.tgz"
+        },
+        "chmodr": {
+          "version": "0.1.0",
+          "from": "chmodr@latest"
+        },
+        "chownr": {
+          "version": "0.0.1",
+          "from": "../chownr"
+        },
+        "cmd-shim": {
+          "version": "1.1.2",
+          "from": "cmd-shim@~1.1.1",
+          "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-1.1.2.tgz"
+        },
+        "columnify": {
+          "version": "1.1.0",
+          "from": "columnify@latest",
+          "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.1.0.tgz",
           "dependencies": {
-            "combined-stream": {
-              "version": "0.0.4",
-              "from": "combined-stream@~0.0.4",
+            "strip-ansi": {
+              "version": "0.2.2",
+              "from": "strip-ansi@^0.2.1",
+              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.2.2.tgz",
               "dependencies": {
-                "delayed-stream": {
-                  "version": "0.0.5",
-                  "from": "delayed-stream@0.0.5"
+                "ansi-regex": {
+                  "version": "0.1.0",
+                  "from": "ansi-regex@^0.1.0",
+                  "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.1.0.tgz"
                 }
               }
             },
-            "async": {
-              "version": "0.1.22",
-              "from": "async@~0.1.9"
+            "wcwidth.js": {
+              "version": "0.0.4",
+              "from": "wcwidth.js@~0.0.4",
+              "resolved": "https://registry.npmjs.org/wcwidth.js/-/wcwidth.js-0.0.4.tgz",
+              "dependencies": {
+                "underscore": {
+                  "version": "1.6.0",
+                  "from": "underscore@>= 1.3.0",
+                  "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
+                }
+              }
             }
           }
         },
-        "mime": {
-          "version": "1.2.9",
-          "from": "mime@~1.2.7"
-        }
-      }
-    },
-    "rimraf": {
-      "version": "2.2.8",
-      "from": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz"
-    },
-    "rjson": {
-      "version": "0.2.4",
-      "from": "rjson@0.2.4",
-      "dependencies": {
-        "commander": {
-          "version": "1.1.1",
-          "from": "commander@1.1.1",
+        "editor": {
+          "version": "0.1.0",
+          "from": "editor@latest",
+          "resolved": "https://registry.npmjs.org/editor/-/editor-0.1.0.tgz"
+        },
+        "fstream": {
+          "version": "1.0.0",
+          "from": "fstream@latest"
+        },
+        "fstream-npm": {
+          "version": "1.0.0",
+          "from": "fstream-npm@latest",
           "dependencies": {
-            "keypress": {
-              "version": "0.1.0",
-              "from": "keypress@0.1.0"
+            "fstream-ignore": {
+              "version": "1.0.1",
+              "from": "fstream-ignore@^1.0.0"
             }
           }
-        }
-      }
-    },
-    "socket.io": {
-      "version": "0.9.16",
-      "from": "socket.io@0.9.16",
-      "dependencies": {
-        "socket.io-client": {
-          "version": "0.9.16",
-          "from": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz",
-          "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz",
+        },
+        "github-url-from-git": {
+          "version": "1.3.0",
+          "from": "github-url-from-git@latest",
+          "resolved": "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.3.0.tgz"
+        },
+        "github-url-from-username-repo": {
+          "version": "0.2.0",
+          "from": "github-url-from-username-repo@latest",
+          "resolved": "https://registry.npmjs.org/github-url-from-username-repo/-/github-url-from-username-repo-0.2.0.tgz"
+        },
+        "glob": {
+          "version": "4.0.5",
+          "from": "glob@latest",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-4.0.5.tgz"
+        },
+        "graceful-fs": {
+          "version": "3.0.2",
+          "from": "graceful-fs@~3.0.0",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.2.tgz"
+        },
+        "inflight": {
+          "version": "1.0.1",
+          "from": "inflight@~1.0.1",
+          "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.1.tgz"
+        },
+        "ini": {
+          "version": "1.2.1",
+          "from": "ini@latest",
+          "resolved": "https://registry.npmjs.org/ini/-/ini-1.2.1.tgz"
+        },
+        "init-package-json": {
+          "version": "1.0.0",
+          "from": "init-package-json@1.0.0",
+          "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-1.0.0.tgz",
           "dependencies": {
-            "uglify-js": {
-              "version": "1.2.5",
-              "from": "uglify-js@1.2.5"
-            },
-            "ws": {
-              "version": "0.4.31",
-              "from": "ws@0.4.31",
-              "dependencies": {
-                "commander": {
-                  "version": "0.6.1",
-                  "from": "commander@0.6.1"
-                },
-                "nan": {
-                  "version": "0.3.2",
-                  "from": "nan@0.3.2"
-                },
-                "tinycolor": {
-                  "version": "0.0.1",
-                  "from": "tinycolor@0.0.1"
-                },
-                "options": {
-                  "version": "0.0.5",
-                  "from": "options@0.0.5"
-                }
-              }
-            },
-            "xmlhttprequest": {
-              "version": "1.4.2",
-              "from": "xmlhttprequest@1.4.2"
-            },
-            "active-x-obfuscator": {
-              "version": "0.0.1",
-              "from": "active-x-obfuscator@0.0.1",
+            "promzard": {
+              "version": "0.2.2",
+              "from": "promzard@~0.2.0",
+              "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.2.2.tgz"
+            }
+          }
+        },
+        "lockfile": {
+          "version": "0.4.2",
+          "from": "lockfile@0.4.2",
+          "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-0.4.2.tgz"
+        },
+        "lru-cache": {
+          "version": "2.5.0",
+          "from": "lru-cache@latest"
+        },
+        "minimatch": {
+          "version": "1.0.0",
+          "from": "minimatch@latest",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz",
+          "dependencies": {
+            "sigmund": {
+              "version": "1.0.0",
+              "from": "sigmund@~1.0.0",
+              "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz"
+            }
+          }
+        },
+        "mkdirp": {
+          "version": "0.5.0",
+          "from": "mkdirp@latest",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
+          "dependencies": {
+            "minimist": {
+              "version": "0.0.8",
+              "from": "minimist@0.0.8",
+              "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
+            }
+          }
+        },
+        "node-gyp": {
+          "version": "1.0.1",
+          "from": "node-gyp@latest"
+        },
+        "nopt": {
+          "version": "3.0.1",
+          "from": "nopt@latest"
+        },
+        "npm-cache-filename": {
+          "version": "1.0.1",
+          "from": "npm-cache-filename@latest",
+          "resolved": "https://registry.npmjs.org/npm-cache-filename/-/npm-cache-filename-1.0.1.tgz"
+        },
+        "npm-install-checks": {
+          "version": "1.0.2",
+          "from": "npm-install-checks@latest"
+        },
+        "npm-registry-client": {
+          "version": "2.0.4",
+          "from": "npm-registry-client@2.0.4",
+          "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-2.0.4.tgz"
+        },
+        "npm-user-validate": {
+          "version": "0.1.0",
+          "from": "npm-user-validate@latest"
+        },
+        "npmconf": {
+          "version": "1.1.5",
+          "from": "npmconf@1.1.5",
+          "resolved": "https://registry.npmjs.org/npmconf/-/npmconf-1.1.5.tgz",
+          "dependencies": {
+            "config-chain": {
+              "version": "1.1.8",
+              "from": "config-chain@~1.1.8",
+              "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.8.tgz",
               "dependencies": {
-                "zeparser": {
-                  "version": "0.0.5",
-                  "from": "zeparser@0.0.5"
+                "proto-list": {
+                  "version": "1.2.3",
+                  "from": "proto-list@~1.2.1",
+                  "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.3.tgz"
                 }
               }
             }
           }
         },
-        "policyfile": {
-          "version": "0.0.4",
-          "from": "https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz",
-          "resolved": "https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz"
+        "npmlog": {
+          "version": "0.1.1",
+          "from": "npmlog@latest"
         },
-        "base64id": {
+        "once": {
+          "version": "1.3.0",
+          "from": "once@latest"
+        },
+        "opener": {
+          "version": "1.3.0",
+          "from": "opener@latest"
+        },
+        "osenv": {
           "version": "0.1.0",
-          "from": "base64id@0.1.0"
+          "from": "osenv@~0.1.0"
         },
-        "redis": {
-          "version": "0.7.3",
-          "from": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz",
-          "resolved": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz"
-        }
-      }
-    },
-    "underscore": {
-      "version": "1.4.4",
-      "from": "underscore@1.4.4"
-    },
-    "winston": {
-      "version": "0.7.3",
-      "from": "winston@0.7.3",
-      "dependencies": {
-        "cycle": {
-          "version": "1.0.3",
-          "from": "cycle@1.0.3"
+        "path-is-inside": {
+          "version": "1.0.1",
+          "from": "path-is-inside@1.0.1",
+          "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.1.tgz"
         },
-        "eyes": {
-          "version": "0.1.8",
-          "from": "eyes@0.1.8"
+        "read": {
+          "version": "1.0.5",
+          "from": "read@latest",
+          "dependencies": {
+            "mute-stream": {
+              "version": "0.0.4",
+              "from": "mute-stream@~0.0.4"
+            }
+          }
         },
-        "pkginfo": {
-          "version": "0.3.0",
-          "from": "pkginfo@0.3.0"
+        "read-installed": {
+          "version": "2.0.5",
+          "from": "read-installed@latest",
+          "dependencies": {
+            "util-extend": {
+              "version": "1.0.1",
+              "from": "util-extend@^1.0.1",
+              "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.1.tgz"
+            }
+          }
+        },
+        "read-package-json": {
+          "version": "1.2.6",
+          "from": "read-package-json@latest",
+          "dependencies": {
+            "normalize-package-data": {
+              "version": "1.0.0",
+              "from": "normalize-package-data@^1.0.0"
+            }
+          }
         },
         "request": {
-          "version": "2.16.6",
-          "from": "request@2.16.6",
+          "version": "2.30.0",
+          "from": "request@latest",
           "dependencies": {
+            "qs": {
+              "version": "0.6.6",
+              "from": "qs@~0.6.0"
+            },
+            "json-stringify-safe": {
+              "version": "5.0.0",
+              "from": "json-stringify-safe@~5.0.0"
+            },
+            "forever-agent": {
+              "version": "0.5.0",
+              "from": "forever-agent@~0.5.0"
+            },
+            "node-uuid": {
+              "version": "1.4.1",
+              "from": "node-uuid@~1.4.0"
+            },
+            "mime": {
+              "version": "1.2.11",
+              "from": "mime@~1.2.9"
+            },
+            "tough-cookie": {
+              "version": "0.9.15",
+              "from": "tough-cookie@~0.9.15",
+              "dependencies": {
+                "punycode": {
+                  "version": "1.2.3",
+                  "from": "punycode@>=0.2.0"
+                }
+              }
+            },
             "form-data": {
-              "version": "0.0.10",
-              "from": "form-data@0.0.10",
+              "version": "0.1.2",
+              "from": "form-data@~0.1.0",
               "dependencies": {
                 "combined-stream": {
                   "version": "0.0.4",
-                  "from": "combined-stream@0.0.4",
+                  "from": "combined-stream@~0.0.4",
                   "dependencies": {
                     "delayed-stream": {
                       "version": "0.0.5",
-                      "from": "delayed-stream@0.0.5",
-                      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
+                      "from": "delayed-stream@0.0.5"
                     }
                   }
+                },
+                "async": {
+                  "version": "0.2.9",
+                  "from": "async@~0.2.9"
                 }
               }
             },
-            "mime": {
-              "version": "1.2.11",
-              "from": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
-              "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
+            "tunnel-agent": {
+              "version": "0.3.0",
+              "from": "tunnel-agent@~0.3.0"
+            },
+            "http-signature": {
+              "version": "0.10.0",
+              "from": "http-signature@~0.10.0",
+              "dependencies": {
+                "assert-plus": {
+                  "version": "0.1.2",
+                  "from": "assert-plus@0.1.2"
+                },
+                "asn1": {
+                  "version": "0.1.11",
+                  "from": "asn1@0.1.11"
+                },
+                "ctype": {
+                  "version": "0.5.2",
+                  "from": "ctype@0.5.2"
+                }
+              }
+            },
+            "oauth-sign": {
+              "version": "0.3.0",
+              "from": "oauth-sign@~0.3.0"
             },
             "hawk": {
-              "version": "0.10.2",
-              "from": "hawk@0.10.2",
+              "version": "1.0.0",
+              "from": "hawk@~1.0.0",
               "dependencies": {
                 "hoek": {
-                  "version": "0.7.6",
-                  "from": "hoek@0.7.6"
+                  "version": "0.9.1",
+                  "from": "hoek@0.9.x"
                 },
                 "boom": {
-                  "version": "0.3.8",
-                  "from": "boom@0.3.8"
+                  "version": "0.4.2",
+                  "from": "boom@0.4.x"
                 },
                 "cryptiles": {
-                  "version": "0.1.3",
-                  "from": "cryptiles@0.1.3"
+                  "version": "0.2.2",
+                  "from": "cryptiles@0.2.x"
                 },
                 "sntp": {
-                  "version": "0.1.4",
-                  "from": "sntp@0.1.4"
+                  "version": "0.2.4",
+                  "from": "sntp@0.2.x"
                 }
               }
             },
-            "node-uuid": {
-              "version": "1.4.1",
-              "from": "node-uuid@1.4.1"
-            },
-            "cookie-jar": {
-              "version": "0.2.0",
-              "from": "cookie-jar@0.2.0"
-            },
-            "aws-sign": {
-              "version": "0.2.0",
-              "from": "aws-sign@0.2.0"
-            },
-            "oauth-sign": {
-              "version": "0.2.0",
-              "from": "oauth-sign@0.2.0"
-            },
-            "forever-agent": {
-              "version": "0.2.0",
-              "from": "forever-agent@0.2.0"
-            },
-            "tunnel-agent": {
-              "version": "0.2.0",
-              "from": "tunnel-agent@0.2.0"
-            },
-            "json-stringify-safe": {
-              "version": "3.0.0",
-              "from": "json-stringify-safe@3.0.0"
-            },
-            "qs": {
-              "version": "0.5.6",
-              "from": "qs@0.5.6"
+            "aws-sign2": {
+              "version": "0.5.0",
+              "from": "aws-sign2@~0.5.0"
             }
           }
         },
-        "stack-trace": {
-          "version": "0.0.9",
-          "from": "stack-trace@0.0.9"
+        "retry": {
+          "version": "0.6.0",
+          "from": "retry"
+        },
+        "rimraf": {
+          "version": "2.2.8",
+          "from": "rimraf@latest",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz"
+        },
+        "semver": {
+          "version": "2.3.0",
+          "from": "semver@latest"
+        },
+        "sha": {
+          "version": "1.2.4",
+          "from": "sha@latest",
+          "resolved": "https://registry.npmjs.org/sha/-/sha-1.2.4.tgz",
+          "dependencies": {
+            "readable-stream": {
+              "version": "1.0.27-1",
+              "from": "readable-stream@1.0",
+              "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz",
+              "dependencies": {
+                "core-util-is": {
+                  "version": "1.0.1",
+                  "from": "core-util-is@~1.0.0",
+                  "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
+                },
+                "isarray": {
+                  "version": "0.0.1",
+                  "from": "isarray@0.0.1",
+                  "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+                },
+                "string_decoder": {
+                  "version": "0.10.25-1",
+                  "from": "string_decoder@~0.10.x",
+                  "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz"
+                }
+              }
+            }
+          }
+        },
+        "slide": {
+          "version": "1.1.5",
+          "from": "slide@latest"
+        },
+        "sorted-object": {
+          "version": "1.0.0",
+          "from": "sorted-object@"
+        },
+        "tar": {
+          "version": "1.0.0",
+          "from": "tar@latest"
+        },
+        "text-table": {
+          "version": "0.2.0",
+          "from": "text-table@~0.2.0"
+        },
+        "uid-number": {
+          "version": "0.0.5",
+          "from": "uid-number@latest",
+          "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.5.tgz"
+        },
+        "which": {
+          "version": "1.0.5",
+          "from": "which@1"
+        },
+        "inherits": {
+          "version": "2.0.1",
+          "from": "inherits@"
+        }
+      }
+    },
+    "oauth2orize": {
+      "version": "0.1.0",
+      "from": "oauth2orize@0.1.x",
+      "dependencies": {
+        "debug": {
+          "version": "0.7.4",
+          "from": "debug@0.7.x",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz"
+        }
+      }
+    },
+    "oauth2orize-jwt-bearer": {
+      "version": "0.1.0",
+      "from": "oauth2orize-jwt-bearer@0.1.x",
+      "dependencies": {
+        "pkginfo": {
+          "version": "0.2.3",
+          "from": "pkginfo@0.2.x"
+        }
+      }
+    },
+    "passport": {
+      "version": "0.1.18",
+      "from": "passport@0.1.x",
+      "dependencies": {
+        "pkginfo": {
+          "version": "0.2.3",
+          "from": "pkginfo@0.2.x"
+        },
+        "pause": {
+          "version": "0.0.1",
+          "from": "pause@0.0.1"
+        }
+      }
+    },
+    "passport-http": {
+      "version": "0.2.2",
+      "from": "passport-http@0.2.x",
+      "dependencies": {
+        "pkginfo": {
+          "version": "0.2.3",
+          "from": "pkginfo@0.2.x"
+        }
+      }
+    },
+    "passport-http-bearer": {
+      "version": "0.2.1",
+      "from": "passport-http-bearer@0.2.x",
+      "dependencies": {
+        "pkginfo": {
+          "version": "0.2.3",
+          "from": "pkginfo@0.2.x"
+        }
+      }
+    },
+    "passport-local": {
+      "version": "0.1.6",
+      "from": "passport-local@0.1.x",
+      "dependencies": {
+        "pkginfo": {
+          "version": "0.2.3",
+          "from": "pkginfo@0.2.x"
+        }
+      }
+    },
+    "passport-oauth2-client-password": {
+      "version": "0.1.1",
+      "from": "passport-oauth2-client-password@0.1.x",
+      "dependencies": {
+        "pkginfo": {
+          "version": "0.2.3",
+          "from": "pkginfo@0.2.x"
         }
       }
     },
-    "underscore.string": {
-      "version": "2.3.3",
-      "from": "underscore.string@2.3.3"
-    },
-    "ursa": {
-      "version": "0.8.0",
-      "from": "ursa@0.8.0"
-    },
-    "xtuple-query": {
-      "version": "1.0.0",
-      "from": "xtuple-query@1.0.0",
+    "passport-oauth2-jwt-bearer": {
+      "version": "0.1.1",
+      "from": "passport-oauth2-jwt-bearer@0.1.x",
       "dependencies": {
-        "congruence": {
-          "version": "1.2.3",
-          "from": "https://registry.npmjs.org/congruence/-/congruence-1.2.3.tgz",
-          "resolved": "https://registry.npmjs.org/congruence/-/congruence-1.2.3.tgz"
-        },
-        "underscore": {
-          "version": "1.5.2",
-          "from": "underscore@1.5.2"
+        "pkginfo": {
+          "version": "0.2.3",
+          "from": "pkginfo@0.2.x"
         }
       }
     },
-    "googleapis": {
-      "version": "0.4.7",
-      "from": "googleapis@0.4.7",
+    "paynode": {
+      "version": "0.3.6",
+      "from": "paynode@0.3.6",
       "dependencies": {
-        "request": {
-          "version": "2.25.0",
-          "from": "request@2.25.0",
+        "braintree": {
+          "version": "1.17.0",
+          "from": "braintree@*",
+          "resolved": "https://registry.npmjs.org/braintree/-/braintree-1.17.0.tgz",
           "dependencies": {
-            "qs": {
-              "version": "0.6.6",
-              "from": "qs@0.6.6"
-            },
-            "json-stringify-safe": {
-              "version": "5.0.0",
-              "from": "json-stringify-safe@5.0.0"
-            },
-            "forever-agent": {
-              "version": "0.5.2",
-              "from": "forever-agent@0.5.2"
+            "dateformat": {
+              "version": "1.0.1-1.2.3",
+              "from": "dateformat@=1.0.1-1.2.3",
+              "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.1-1.2.3.tgz"
             },
-            "tunnel-agent": {
-              "version": "0.3.0",
-              "from": "tunnel-agent@0.3.0"
+            "semver": {
+              "version": "2.2.1",
+              "from": "semver@=2.2.1",
+              "resolved": "https://registry.npmjs.org/semver/-/semver-2.2.1.tgz"
             },
-            "http-signature": {
-              "version": "0.10.0",
-              "from": "http-signature@0.10.0",
+            "readable-stream": {
+              "version": "1.1.10",
+              "from": "readable-stream@=1.1.10",
+              "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.10.tgz",
               "dependencies": {
-                "assert-plus": {
-                  "version": "0.1.2",
-                  "from": "assert-plus@0.1.2",
-                  "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz"
+                "core-util-is": {
+                  "version": "1.0.1",
+                  "from": "core-util-is@~1.0.0"
                 },
-                "asn1": {
-                  "version": "0.1.11",
-                  "from": "asn1@0.1.11",
-                  "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
+                "string_decoder": {
+                  "version": "0.10.31",
+                  "from": "string_decoder@~0.10.x",
+                  "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
                 },
-                "ctype": {
-                  "version": "0.5.2",
-                  "from": "ctype@0.5.2",
-                  "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz"
+                "debuglog": {
+                  "version": "0.0.2",
+                  "from": "debuglog@0.0.2",
+                  "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz"
                 }
               }
             },
-            "hawk": {
-              "version": "1.0.0",
-              "from": "hawk@1.0.0",
+            "underscore": {
+              "version": "1.3.1",
+              "from": "underscore@=1.3.1",
+              "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.3.1.tgz"
+            },
+            "xml2js": {
+              "version": "0.1.13",
+              "from": "xml2js@=0.1.13",
+              "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.1.13.tgz",
               "dependencies": {
-                "hoek": {
-                  "version": "0.9.1",
-                  "from": "hoek@0.9.1"
-                },
-                "boom": {
-                  "version": "0.4.2",
-                  "from": "boom@0.4.2"
-                },
-                "cryptiles": {
-                  "version": "0.2.2",
-                  "from": "cryptiles@0.2.2"
-                },
-                "sntp": {
-                  "version": "0.2.4",
-                  "from": "sntp@0.2.4"
+                "sax": {
+                  "version": "0.6.0",
+                  "from": "sax@>=0.1.1"
                 }
               }
             },
-            "aws-sign": {
-              "version": "0.3.0",
-              "from": "aws-sign@0.3.0"
-            },
-            "oauth-sign": {
-              "version": "0.3.0",
-              "from": "oauth-sign@0.3.0"
-            },
-            "cookie-jar": {
-              "version": "0.3.0",
-              "from": "cookie-jar@0.3.0"
-            },
-            "node-uuid": {
-              "version": "1.4.1",
-              "from": "node-uuid@1.4.1"
-            },
-            "mime": {
-              "version": "1.2.11",
-              "from": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
-              "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
-            },
-            "form-data": {
+            "source-map-support": {
               "version": "0.1.2",
-              "from": "form-data@0.1.2",
+              "from": "source-map-support@=0.1.2",
+              "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.1.2.tgz",
               "dependencies": {
-                "combined-stream": {
-                  "version": "0.0.4",
-                  "from": "combined-stream@0.0.4",
+                "source-map": {
+                  "version": "0.1.8",
+                  "from": "source-map@0.1.8",
+                  "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.8.tgz",
                   "dependencies": {
-                    "delayed-stream": {
-                      "version": "0.0.5",
-                      "from": "delayed-stream@0.0.5",
-                      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
+                    "amdefine": {
+                      "version": "0.1.0",
+                      "from": "amdefine@>=0.0.4"
                     }
                   }
-                },
-                "async": {
-                  "version": "0.2.10",
-                  "from": "async@0.2.10"
                 }
               }
             }
           }
+        }
+      }
+    },
+    "pg": {
+      "version": "0.14.1",
+      "from": "pg@0.14.x",
+      "resolved": "https://registry.npmjs.org/pg/-/pg-0.14.1.tgz",
+      "dependencies": {
+        "generic-pool": {
+          "version": "2.0.4",
+          "from": "generic-pool@~2.0.2"
         },
-        "async": {
-          "version": "0.2.6",
-          "from": "https://registry.npmjs.org/async/-/async-0.2.6.tgz",
-          "resolved": "https://registry.npmjs.org/async/-/async-0.2.6.tgz"
-        },
-        "gapitoken": {
+        "deprecate": {
           "version": "0.1.0",
-          "from": "https://registry.npmjs.org/gapitoken/-/gapitoken-0.1.0.tgz",
-          "resolved": "https://registry.npmjs.org/gapitoken/-/gapitoken-0.1.0.tgz",
+          "from": "deprecate@~0.1.0"
+        }
+      }
+    },
+    "request": {
+      "version": "2.14.0",
+      "from": "request@2.14.x",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.14.0.tgz",
+      "dependencies": {
+        "form-data": {
+          "version": "0.0.7",
+          "from": "form-data@~0.0.3",
           "dependencies": {
-            "jws": {
-              "version": "0.0.2",
-              "from": "jws@0.0.2",
+            "combined-stream": {
+              "version": "0.0.4",
+              "from": "combined-stream@~0.0.4",
               "dependencies": {
-                "tap": {
-                  "version": "0.3.3",
-                  "from": "tap@0.3.3",
-                  "dependencies": {
-                    "inherits": {
-                      "version": "1.0.0"
-                    },
-                    "yamlish": {
-                      "version": "0.0.5"
-                    },
-                    "slide": {
-                      "version": "1.1.5",
-                      "from": "slide@1.1.5"
-                    },
-                    "runforcover": {
-                      "version": "0.0.2",
-                      "from": "runforcover@0.0.2",
-                      "dependencies": {
-                        "bunker": {
-                          "version": "0.1.2",
-                          "from": "bunker@0.1.2",
-                          "dependencies": {
-                            "burrito": {
-                              "version": "0.2.12",
-                              "from": "burrito@0.2.12",
-                              "dependencies": {
-                                "traverse": {
-                                  "version": "0.5.2",
-                                  "from": "traverse@0.5.2"
-                                },
-                                "uglify-js": {
-                                  "version": "1.1.1",
-                                  "from": "uglify-js@1.1.1"
-                                }
-                              }
-                            }
-                          }
-                        }
-                      }
-                    },
-                    "nopt": {
-                      "version": "2.2.1",
-                      "from": "https://registry.npmjs.org/nopt/-/nopt-2.2.1.tgz",
-                      "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.2.1.tgz",
-                      "dependencies": {
-                        "abbrev": {
-                          "version": "1.0.5",
-                          "from": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz",
-                          "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz"
-                        }
-                      }
-                    },
-                    "mkdirp": {
-                      "version": "0.3.5",
-                      "from": "mkdirp@0.3.5"
-                    },
-                    "difflet": {
-                      "version": "0.2.6",
-                      "from": "difflet@0.2.6",
-                      "dependencies": {
-                        "traverse": {
-                          "version": "0.6.6",
-                          "from": "traverse@0.6.6"
-                        },
-                        "charm": {
-                          "version": "0.1.2",
-                          "from": "charm@0.1.2"
-                        },
-                        "deep-is": {
-                          "version": "0.1.2",
-                          "from": "deep-is@0.1.2"
-                        }
-                      }
-                    },
-                    "deep-equal": {
-                      "version": "0.0.0",
-                      "from": "deep-equal@0.0.0"
-                    },
-                    "buffer-equal": {
-                      "version": "0.0.0",
-                      "from": "buffer-equal@0.0.0"
-                    }
-                  }
+                "delayed-stream": {
+                  "version": "0.0.5",
+                  "from": "delayed-stream@0.0.5"
+                }
+              }
+            },
+            "async": {
+              "version": "0.1.22",
+              "from": "async@~0.1.9"
+            }
+          }
+        },
+        "mime": {
+          "version": "1.2.9",
+          "from": "mime@~1.2.7"
+        }
+      }
+    },
+    "rimraf": {
+      "version": "2.2.8",
+      "from": "rimraf@2.2.x"
+    },
+    "rjson": {
+      "version": "0.2.4",
+      "from": "rjson@~0.2.4",
+      "dependencies": {
+        "commander": {
+          "version": "1.1.1",
+          "from": "commander@~1.1.1",
+          "dependencies": {
+            "keypress": {
+              "version": "0.1.0",
+              "from": "keypress@0.1.x"
+            }
+          }
+        }
+      }
+    },
+    "socket.io": {
+      "version": "0.9.17",
+      "from": "socket.io@0.9.x",
+      "dependencies": {
+        "socket.io-client": {
+          "version": "0.9.16",
+          "from": "socket.io-client@0.9.16",
+          "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz",
+          "dependencies": {
+            "uglify-js": {
+              "version": "1.2.5",
+              "from": "uglify-js@1.2.5",
+              "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.2.5.tgz"
+            },
+            "ws": {
+              "version": "0.4.32",
+              "from": "ws@0.4.x",
+              "dependencies": {
+                "commander": {
+                  "version": "2.1.0",
+                  "from": "commander@~2.1.0",
+                  "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz"
+                },
+                "nan": {
+                  "version": "1.0.0",
+                  "from": "nan@~1.0.0"
                 },
-                "base64url": {
-                  "version": "0.0.3",
-                  "from": "https://registry.npmjs.org/base64url/-/base64url-0.0.3.tgz",
-                  "resolved": "https://registry.npmjs.org/base64url/-/base64url-0.0.3.tgz"
+                "tinycolor": {
+                  "version": "0.0.1",
+                  "from": "tinycolor@0.x"
+                },
+                "options": {
+                  "version": "0.0.5",
+                  "from": "options@>=0.0.5"
+                }
+              }
+            },
+            "xmlhttprequest": {
+              "version": "1.4.2",
+              "from": "xmlhttprequest@1.4.2",
+              "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.4.2.tgz"
+            },
+            "active-x-obfuscator": {
+              "version": "0.0.1",
+              "from": "active-x-obfuscator@0.0.1",
+              "dependencies": {
+                "zeparser": {
+                  "version": "0.0.5",
+                  "from": "zeparser@0.0.5"
                 }
               }
             }
           }
+        },
+        "policyfile": {
+          "version": "0.0.4",
+          "from": "policyfile@0.0.4",
+          "resolved": "https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz"
+        },
+        "base64id": {
+          "version": "0.1.0",
+          "from": "base64id@0.1.0"
+        },
+        "redis": {
+          "version": "0.7.3",
+          "from": "redis@0.7.3",
+          "resolved": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz"
         }
       }
     },
-    "chai": {
-      "version": "1.5.0",
-      "from": "chai@1.5.x"
+    "underscore": {
+      "version": "1.4.4",
+      "from": "underscore@1.4.x",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz"
     },
-    "csslint": {
-      "version": "0.10.0",
-      "from": "csslint@~0.10.0",
-      "dependencies": {
-        "parserlib": {
-          "version": "0.2.5",
-          "from": "parserlib@~0.2.2"
-        }
-      }
+    "underscore.string": {
+      "version": "2.3.3",
+      "from": "underscore.string@~2.3.3"
     },
-    "mocha": {
-      "version": "1.9.0",
-      "from": "mocha@1.9.x",
+    "winston": {
+      "version": "0.7.3",
+      "from": "winston@0.7.x",
       "dependencies": {
-        "commander": {
-          "version": "0.6.1",
-          "from": "commander@0.6.1"
+        "cycle": {
+          "version": "1.0.3",
+          "from": "cycle@1.0.x"
         },
-        "growl": {
-          "version": "1.7.0",
-          "from": "growl@1.7.x"
+        "eyes": {
+          "version": "0.1.8",
+          "from": "eyes@0.1.x"
         },
-        "jade": {
-          "version": "0.26.3",
-          "from": "jade@0.26.3",
+        "pkginfo": {
+          "version": "0.3.0",
+          "from": "pkginfo@0.3.x",
+          "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.0.tgz"
+        },
+        "request": {
+          "version": "2.16.6",
+          "from": "request@2.16.x",
           "dependencies": {
-            "mkdirp": {
-              "version": "0.3.0",
-              "from": "mkdirp@0.3.0"
+            "form-data": {
+              "version": "0.0.10",
+              "from": "form-data@~0.0.3",
+              "dependencies": {
+                "combined-stream": {
+                  "version": "0.0.5",
+                  "from": "combined-stream@~0.0.4",
+                  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.5.tgz",
+                  "dependencies": {
+                    "delayed-stream": {
+                      "version": "0.0.5",
+                      "from": "delayed-stream@0.0.5",
+                      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
+                    }
+                  }
+                }
+              }
+            },
+            "mime": {
+              "version": "1.2.11",
+              "from": "mime@~1.2.7"
+            },
+            "hawk": {
+              "version": "0.10.2",
+              "from": "hawk@~0.10.2",
+              "dependencies": {
+                "hoek": {
+                  "version": "0.7.6",
+                  "from": "hoek@0.7.x"
+                },
+                "boom": {
+                  "version": "0.3.8",
+                  "from": "boom@0.3.x"
+                },
+                "cryptiles": {
+                  "version": "0.1.3",
+                  "from": "cryptiles@0.1.x"
+                },
+                "sntp": {
+                  "version": "0.1.4",
+                  "from": "sntp@0.1.x"
+                }
+              }
+            },
+            "node-uuid": {
+              "version": "1.4.1",
+              "from": "node-uuid@~1.4.0"
+            },
+            "cookie-jar": {
+              "version": "0.2.0",
+              "from": "cookie-jar@~0.2.0"
+            },
+            "aws-sign": {
+              "version": "0.2.0",
+              "from": "aws-sign@~0.2.0",
+              "resolved": "https://registry.npmjs.org/aws-sign/-/aws-sign-0.2.0.tgz"
+            },
+            "oauth-sign": {
+              "version": "0.2.0",
+              "from": "oauth-sign@~0.2.0"
+            },
+            "forever-agent": {
+              "version": "0.2.0",
+              "from": "forever-agent@~0.2.0"
+            },
+            "tunnel-agent": {
+              "version": "0.2.0",
+              "from": "tunnel-agent@~0.2.0"
+            },
+            "json-stringify-safe": {
+              "version": "3.0.0",
+              "from": "json-stringify-safe@~3.0.0"
+            },
+            "qs": {
+              "version": "0.5.6",
+              "from": "qs@~0.5.4"
             }
           }
         },
-        "diff": {
-          "version": "1.0.2",
-          "from": "diff@1.0.2"
-        },
-        "debug": {
-          "version": "1.0.4",
-          "from": "debug@*",
+        "stack-trace": {
+          "version": "0.0.9",
+          "from": "stack-trace@0.0.x"
+        }
+      }
+    },
+    "xtuple-linguist": {
+      "version": "0.1.1",
+      "from": "xtuple-linguist@0.1.x"
+    },
+    "xtuple-query": {
+      "version": "1.0.2",
+      "from": "xtuple-query@~1.0.0",
+      "dependencies": {
+        "congruence": {
+          "version": "1.2.4",
+          "from": "congruence@1.2.4",
+          "resolved": "https://registry.npmjs.org/congruence/-/congruence-1.2.4.tgz",
           "dependencies": {
-            "ms": {
-              "version": "0.6.2",
-              "from": "ms@0.6.2"
+            "moment": {
+              "version": "2.4.0",
+              "from": "moment@2.4.0",
+              "resolved": "https://registry.npmjs.org/moment/-/moment-2.4.0.tgz"
+            },
+            "underscore": {
+              "version": "1.5.2",
+              "from": "underscore@1.5.2"
             }
           }
         },
-        "mkdirp": {
-          "version": "0.3.3",
-          "from": "mkdirp@0.3.3"
+        "moment": {
+          "version": "2.6.0",
+          "from": "moment@2.6.0",
+          "resolved": "https://registry.npmjs.org/moment/-/moment-2.6.0.tgz"
         },
-        "ms": {
-          "version": "0.3.0",
-          "from": "ms@0.3.0"
+        "underscore": {
+          "version": "1.6.0",
+          "from": "underscore@1.6.0",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
         }
       }
     },
     "zombie": {
       "version": "1.4.1",
       "from": "zombie@1.4.x",
+      "resolved": "https://registry.npmjs.org/zombie/-/zombie-1.4.1.tgz",
       "dependencies": {
         "eventsource": {
           "version": "0.0.10",
-          "from": "eventsource@~0.0.5"
+          "from": "eventsource@~0.0.5",
+          "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.0.10.tgz"
         },
         "jsdom": {
           "version": "0.2.19",
           "from": "jsdom@~0.2.15",
+          "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-0.2.19.tgz",
           "dependencies": {
             "htmlparser": {
               "version": "1.7.7",
         },
         "q": {
           "version": "0.8.12",
-          "from": "q@~0.8.6"
+          "from": "q@~0.8.6",
+          "resolved": "https://registry.npmjs.org/q/-/q-0.8.12.tgz"
         },
         "request": {
           "version": "2.10.0",
           }
         }
       }
-    },
-    "html5": {
-      "version": "0.3.13",
-      "from": "html5@0.3.13",
-      "dependencies": {
-        "jsdom": {
-          "version": "0.11.1",
-          "from": "jsdom@>= 0.6.0",
-          "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-0.11.1.tgz",
-          "dependencies": {
-            "htmlparser2": {
-              "version": "3.7.3",
-              "from": "htmlparser2@>= 3.1.5 <4",
-              "dependencies": {
-                "domhandler": {
-                  "version": "2.2.0",
-                  "from": "domhandler@2.2"
-                },
-                "domutils": {
-                  "version": "1.5.0",
-                  "from": "domutils@1.5"
-                },
-                "domelementtype": {
-                  "version": "1.1.1",
-                  "from": "domelementtype@1"
-                },
-                "readable-stream": {
-                  "version": "1.1.13-1",
-                  "from": "readable-stream@1.1",
-                  "dependencies": {
-                    "core-util-is": {
-                      "version": "1.0.1",
-                      "from": "core-util-is@~1.0.0"
-                    },
-                    "isarray": {
-                      "version": "0.0.1",
-                      "from": "isarray@0.0.1"
-                    },
-                    "string_decoder": {
-                      "version": "0.10.25-1",
-                      "from": "string_decoder@~0.10.x"
-                    },
-                    "inherits": {
-                      "version": "2.0.1",
-                      "from": "inherits@~2.0.1"
-                    }
-                  }
-                },
-                "entities": {
-                  "version": "1.0.0",
-                  "from": "entities@1.0"
-                }
-              }
-            },
-            "nwmatcher": {
-              "version": "1.3.3",
-              "from": "nwmatcher@~1.3.2"
-            },
-            "xmlhttprequest": {
-              "version": "1.6.0",
-              "from": "xmlhttprequest@>=1.5.0"
-            },
-            "cssom": {
-              "version": "0.3.0",
-              "from": "cssom@~0.3.0"
-            },
-            "cssstyle": {
-              "version": "0.2.14",
-              "from": "cssstyle@~0.2.9"
-            },
-            "contextify": {
-              "version": "0.1.8",
-              "from": "contextify@~0.1.5",
-              "dependencies": {
-                "bindings": {
-                  "version": "1.2.1",
-                  "from": "bindings@*",
-                  "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
-                },
-                "nan": {
-                  "version": "1.0.0",
-                  "from": "nan@~1.0.0"
-                }
-              }
-            }
-          }
-        },
-        "opts": {
-          "version": "1.2.2",
-          "from": "opts@~1.2.1"
-        },
-        "html5-entities": {
-          "version": "0.5.1",
-          "from": "html5-entities@~0.5.0"
-        }
-      }
     }
   }
 }
index e28e7aa..88d940f 100644 (file)
@@ -24,7 +24,7 @@
     "less": "1.5.0",
     "moment": "2.4.x",
     "nodemailer": "0.3.x",
-    "npm":"1.2.30",
+    "npm":"1.4.x",
     "node-forge": "0.6.x",
     "oauth2orize": "0.1.x",
     "oauth2orize-jwt-bearer": "0.1.x",
@@ -43,7 +43,7 @@
     "underscore": "1.4.x",
     "winston": "0.7.x",
     "underscore.string": "~2.3.3",
-    "ursa": "0.8.x",
+    "xtuple-linguist": "0.1.x",
     "jquery": "~2.1.1"
   },
   "devDependencies": {
@@ -52,6 +52,7 @@
     "html5": "0.3.13",
     "jshint": "2.4.x",
     "zombie": "1.4.x",
+    "nodemon": "~1.0.15",
     "csslint": "~0.10.0"
   },
   "optionalDependencies": {
@@ -59,7 +60,7 @@
     "googleapis": "~0.4.6"
   },
   "engines": {
-    "node": "0.8.x"
+    "node": "^0.10"
   },
   "main": "node-datasource/main.js",
   "scripts": {
index 531f85b..ee2121b 100644 (file)
@@ -23,7 +23,7 @@ sudo apt-get -q -y install \
   python-software-properties \
   software-properties-common
 
-NODE_VERSION=0.8.26
+NODE_VERSION=0.10.31
 
 DEBDIST=`lsb_release -c -s`
 echo "Trying to install xTuple for platform ${DEBDIST}"
@@ -154,7 +154,7 @@ install_packages() {
   sudo nvm alias xtuple $NODE_VERSION
 
   # use latest npm
-  npm install -g npm 
+  npm install -fg npm@1.4.25
        # npm no longer supports its self-signed certificates
        log "telling npm to use known registrars..."
        npm config set ca ""
index 3a1e08b..469fbd6 100644 (file)
@@ -5,6 +5,7 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
 var _ = require('underscore'),
   async = require('async'),
   buildDatabase = require("./build_database"),
+  buildDictionary = require("./build_dictionary"),
   buildClient = require("./build_client").buildClient,
   defaultExtensions = require("./util/default_extensions").extensions,
   dataSource = require('../../node-datasource/lib/ext/datasource').dataSource,
@@ -103,9 +104,21 @@ var _ = require('underscore'),
           });
           done(null, "Build succeeded." + returnMessage);
         });
+      },
+      function (done) {
+        // step 4: import all dictionary files
+        if (specs[0].clientOnly || specs[0].databaseOnly) {
+          // don't build dictionaries if the user doesn't want us to
+          console.log("Not importing the dictionaries");
+          return done();
+        }
+        var databases = _.map(specs, function (spec) {
+          return spec.database;
+        });
+        async.map(databases, buildDictionary.importAllDictionaries, done);
       }
     ], function (err, results) {
-      buildAllCallback(err, results && results[results.length - 1]);
+      buildAllCallback(err, results && results[results.length - 2]);
     });
   };
 
index 7a6ec62..77ffc44 100644 (file)
@@ -201,14 +201,14 @@ if (typeof XT === 'undefined') {
               source: stringObj.value,
               target: preExistingTranslation
             });
-         } else if ( destinationLang.indexOf('en') === 0 ) {
-            // if locale is en_AU en_GB copy the en_US source: strings to target:
-            stringCallback(null, {
-                key: stringObj.key,
-                source: stringObj.value,
-                target: stringObj.value
-              });
-         } else {
+          } else if ( destinationLang.indexOf('en') === 0 ) {
+             // if locale is en_AU en_GB copy the en_US source: strings to target:
+             stringCallback(null, {
+               key: stringObj.key,
+               source: stringObj.value,
+               target: stringObj.value
+             });
+          } else {
             // ask google (or not)
             autoTranslate(stringObj.value, apiKey, destinationLang, function (err, target) {
               stringCallback(null, {
@@ -217,7 +217,7 @@ if (typeof XT === 'undefined') {
                 target: target
               });
             });
-         };
+         }
         };
         async.map(stringsArray, processString, function (err, strings) {
           extensionCallback(null, {
@@ -262,14 +262,11 @@ if (typeof XT === 'undefined') {
   /**
     Takes a dictionary definition file and inserts the data into the database
    */
-  exports.importDictionary = function (database, filename, masterCallback) {
+  var importDictionary = exports.importDictionary = function (database, filename, masterCallback) {
     var creds = require("../../node-datasource/config").databaseServer;
     creds.database = database;
 
-    // the filename relative unless it starts with a slash
-    if (filename.substring(0, 1) !== '/') {
-      filename = path.join(process.cwd(), filename);
-    }
+    filename = path.resolve(process.cwd(), filename);
     if (path.extname(filename) !== '.js') {
       console.log("Skipping non-dictionary file", filename);
       masterCallback();
@@ -299,4 +296,20 @@ if (typeof XT === 'undefined') {
     });
   };
 
+  exports.importAllDictionaries = function (database, callback) {
+    var translationsDir = path.join(__dirname, "../../node_modules/xtuple-linguist/translations");
+    if (!fs.existsSync(translationsDir)) {
+      console.log("No translations directory found. Ignoring linguist.");
+      return callback();
+    }
+    var importOne = function (dictionary, next) {
+      importDictionary(database, dictionary, next);
+    };
+    var allDictionaries = _.map(fs.readdirSync(translationsDir), function (filename) {
+      return path.join(translationsDir, filename);
+    });
+    async.map(allDictionaries, importOne, callback);
+  };
+
+
 }());
index 4dca75c..3794cfb 100644 (file)
@@ -6,7 +6,7 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
   "use strict";
 
   var async = require("async"),
-    exec = require('child_process').exec,
+    proc = require('child_process'),
     path = require('path'),
     os = require('os'),
     winston = require('winston'),
@@ -35,21 +35,29 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
         var schemaPath = path.join(path.dirname(spec.source), "440_schema.sql");
         winston.info("Building schema for database " + databaseName);
 
-        exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " +
-          creds.port + " -d " + databaseName + " -f " + schemaPath,
-          {maxBuffer: 40000 * 1024 /* 200x default */}, done);
+        var process = proc.spawn('psql', [
+          '-q', '-U', creds.username, '-h', creds.hostname, '--single-transaction', '-p',
+          creds.port, '-d', databaseName, '-f', schemaPath
+        ], { stdio: 'inherit' });
+        process.on('exit', done);
+        
       },
       populateData = function (done) {
         winston.info("Populating data for database " + databaseName + " from " + spec.source);
-        exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " +
-          creds.port + " -d " + databaseName + " -f " + spec.source,
-          {maxBuffer: 40000 * 1024 /* 200x default */}, done);
+        var process = proc.spawn('psql', [
+          '-q', '-U', creds.username, '-h', creds.hostname, '--single-transaction', '-p',
+          creds.port, '-d', databaseName, '-f', spec.source
+        ], { stdio: 'inherit'});
+        process.on('exit', done);
       },
       // use exec to restore the backup. The alternative, reading the backup file into a string to query
       // doesn't work because the backup file is binary.
       restoreBackup = function (done) {
-        exec("pg_restore -U " + creds.username + " -h " + creds.hostname + " -p " +
-          creds.port + " -d " + databaseName + " -j " + os.cpus().length + " " + spec.backup, function (err, res) {
+        var process = proc.spawn('pg_restore', [
+          '-U', creds.username, '-h', creds.hostname, '-p', creds.port, '-d', databaseName,
+          '-j', os.cpus().length, spec.backup
+        ], { stdio: 'inherit' });
+        process.on('exit', function (err, res) {
           if (err) {
             console.log("ignoring restore db error", err);
           }
index 1124833..e387b7e 100644 (file)
     smoke = require("../../lib/smoke");
 
   describe('Configuration Workspaces', function () {
-    this.timeout(30 * 1000);
+    this.timeout(60 * 1000);
 
     before(function (done) {
       zombieAuth.loadApp(done);
     });
 
     it('should all be accessible', function (done) {
-      this.timeout(80 * 1000);
+      this.timeout(120 * 1000);
       var navigator, workspace,
         list,
         i = -1;
index a31a886..2ad8ad4 100644 (file)
@@ -16,7 +16,7 @@
     assert = require("chai").assert;
 
   describe('Workspaces', function () {
-    this.timeout(20 * 1000);
+    this.timeout(60 * 1000);
     it('should log in first', function (done) {
       zombieAuth.loadApp(done);
     });
@@ -83,7 +83,7 @@
     var workspaceContainer, workspace, model, id, moduleContainer;
 
     beforeEach(function (done) {
-      this.timeout(10 * 1000);
+      this.timeout(60 * 1000);
 
       smoke.navigateToExistingWorkspace(XT.app, "XV.ClassCodeList", function (_workspaceContainer) {
         workspaceContainer = _workspaceContainer;
       });
     });
     afterEach(function (done) {
-      this.timeout(10 * 1000);
+      this.timeout(60 * 1000);
 
       // maybe one of the tests already released the lock
       if (!model.hasLockKey()) {
index cf880fc..71f410c 100644 (file)
 
       });
       afterEach(function (done) {
-        this.timeout(10 * 1000);
+        this.timeout(30 * 1000);
 
         // restore permissions
         _.extend(XT.session.privileges.attributes, originalPrivileges);
index 3f1548e..43406d3 100644 (file)
@@ -44,7 +44,8 @@
       });
     };
 
-  describe('Sales Order Workspace', function () {
+  // TODO: move to sales order spec
+  describe.skip('Sales Order Workspace', function () {
     this.timeout(30 * 1000);
 
     //
           moduleContainer = XT.app.$.postbooks;
 
         /** Open the first model's salesOrderLineWorkspace...
-            Copied from gridBox buttonTapped function (expandGridRowButton) 
+            Copied from gridBox buttonTapped function (expandGridRowButton)
         */
         lineItemBox.doChildWorkspace({
           workspace: lineItemBox.getWorkspace(),
           index: lineItemBox.getValue().indexOf(model)
         });
 
-        /** The line item's workspace model has been deleted (DESTROYED_CLEAN). 
+        /** The line item's workspace model has been deleted (DESTROYED_CLEAN).
             Client is now in SalesOrderWorkspace.
         */
         var statusChanged = function () {
 
         model.once("status:DESTROYED_CLEAN", statusChanged);
 
-        // Function to keep checking for notifyPopup showing and then tap yes. 
+        // Function to keep checking for notifyPopup showing and then tap yes.
         // This will fire right after the delete below.
         var notifyPopupInterval = setInterval(function () {
           if (!moduleContainer.$.notifyPopup.showing) { return; }
index e3c4704..7f95c00 100644 (file)
@@ -366,7 +366,7 @@ var _ = require("underscore"),
     // Step 1: load the environment with Zombie
     //
     it('can be loaded with a zombie session', function (done) {
-      this.timeout(40 * 1000);
+      this.timeout(60 * 1000);
       zombieAuth.loadApp({callback: done, verbose: data.verbose,
         loginDataPath: data.loginDataPath});
     });
@@ -383,7 +383,7 @@ var _ = require("underscore"),
     // Step 3: initialize the model to get the ID from the database
     //
     it('can be initialized by fetching an id from the server', function (done) {
-      this.timeout(20 * 1000);
+      this.timeout(60 * 1000);
       init(data, done);
     });
 
@@ -392,13 +392,13 @@ var _ = require("underscore"),
     //
     _.each(data.beforeSetActions || [], function (spec) {
       it(spec.it, function (done) {
-        this.timeout(20 * 1000);
+        this.timeout(60 * 1000);
         spec.action(data, done);
       });
     });
 
     it('can have its values set', function (done) {
-      this.timeout(20 * 1000);
+      this.timeout(60 * 1000);
       data.updated = false;
       setModel(data, done);
     });
@@ -406,14 +406,14 @@ var _ = require("underscore"),
     // if this model has comments, set them on the model
     if (data.commentType) {
       it('can have its comments set', function (done) {
-        this.timeout(20 * 1000);
+        this.timeout(60 * 1000);
         setComments(data, done);
       });
     }
 
     _.each(data.beforeSaveActions || [], function (spec) {
       it(spec.it, function (done) {
-        this.timeout(20 * 1000);
+        this.timeout(60 * 1000);
         spec.action(data, done);
       });
     });
@@ -423,12 +423,12 @@ var _ = require("underscore"),
     //
     if (!data.skipSave) {
       it('can be saved to the database', function (done) {
-        this.timeout(10 * 1000);
+        this.timeout(60 * 1000);
         save(data, done);
       });
       _.each(data.afterSaveActions || [], function (spec) {
         it(spec.it, function (done) {
-          this.timeout(20 * 1000);
+          this.timeout(60 * 1000);
           spec.action(data, done);
         });
       });
@@ -446,7 +446,7 @@ var _ = require("underscore"),
       // Step 7: save the updated model to the database
       //
       it('can be re-saved to the database', function (done) {
-        this.timeout(20 * 1000);
+        this.timeout(60 * 1000);
         save(data, done);
       });
     }
@@ -456,21 +456,21 @@ var _ = require("underscore"),
     //
     _.each(data.beforeDeleteActions || [], function (spec) {
       it(spec.it, function (done) {
-        this.timeout(20 * 1000);
+        this.timeout(60 * 1000);
         spec.action(data, done);
       });
     });
 
     if (!data.skipDelete) {
       it('can be deleted from the database', function (done) {
-        this.timeout(20 * 1000);
+        this.timeout(60 * 1000);
         destroy(data, done);
       });
     }
 
     _.each(data.afterDeleteActions || [], function (spec) {
       it(spec.it, function (done) {
-        this.timeout(20 * 1000);
+        this.timeout(60 * 1000);
         spec.action(data, done);
       });
     });
index 8608927..4ede092 100644 (file)
@@ -161,7 +161,9 @@ require:true, __dirname:true, console:true */
             _.each(spec.extensions, function (extension) {
               it("has privilege " + priv + " declared by the " + extension + " extension", function () {
                 assert.isDefined(_.findWhere(XT.session.relevantPrivileges,
-                  {privilege: priv, module: spec.relevantPrivilegeModule || extension}));
+                  {privilege: priv, module: spec.relevantPrivilegeModule || extension}),
+                  "Perhaps you're adding the privilege in a different module and haven't set the " +
+                  "spec.relevantPrivilegeModule attribute to be that module?");
               });
             });
             /*
index 76af701..1662994 100644 (file)
 
   exports.updateFirstModel = function (test) {
     it('should allow a trivial update to the first model of ' + test.kind, function (done) {
-      this.timeout(20 * 1000);
+      this.timeout(60 * 1000);
       navigateToExistingWorkspace(XT.app, test.kind, function (workspaceContainer) {
         var updateObj,
           statusChanged,
     var workspaceContainer,
       workspace;
     it('can get to a new workspace', function (done) {
-      this.timeout(20 * 1000);
+      this.timeout(60 * 1000);
       navigateToNewWorkspace(XT.app, spec.listKind, function (_workspaceContainer) {
         workspaceContainer = _workspaceContainer;
         done();
     });
     _.each(spec.beforeSaveUIActions || [], function (spec) {
       it(spec.it, function (done) {
-        this.timeout(20 * 1000);
+        this.timeout(60 * 1000);
         spec.action(workspace, done);
       });
     });
     it('can save the workspace', function (done) {
-      this.timeout(20 * 1000);
+      this.timeout(60 * 1000);
       if (spec.captureObject) {
         XG = XG || {};
         XG.capturedId = workspace.value.id;
     });
     _.each(spec.afterSaveUIActions || [], function (spec) {
       it(spec.it, function (done) {
-        this.timeout(20 * 1000);
+        this.timeout(60 * 1000);
         spec.action(workspace, done);
       });
     });
       return;
     }
     it('can delete the item from the list', function (done) {
-      this.timeout(20 * 1000);
+      this.timeout(60 * 1000);
       deleteFromList(XT.app, workspace.value, done);
     });
   };
index a3b3790..579c608 100644 (file)
@@ -2,6 +2,35 @@
 regexp:true, undef:true, strict:true, trailing:true, white:true */
 /*global XT:true, XM:true, XV:true, XZ:true, enyo:true, XG:true */
 
+var _ = require('underscore');
+global.URL = require('url');
+var parse = global.URL.parse;
+var resolve = global.URL.resolve;
+global.URL.parse = function (url) {
+  "use strict";
+  console.log('URL.parse', url);
+  if (_.isObject(url) && _.isString(url.href)) {
+    return parse(url.href);
+  }
+  else {
+    return parse(url);
+  }
+};
+global.URL.resolve = function (from, to) {
+  "use strict";
+  console.log('URL.resolve from', from);
+  console.log('URL.resolve to', to);
+  if (_.isObject(from)) {
+    from = from.href || '/';
+  }
+  if (_.isObject(to)) {
+    to = to.href || '';
+  }
+
+  return resolve(from, to);
+};
+
+
 // global objects
 enyo = {};
 XT = {};
@@ -10,9 +39,11 @@ XM = {};
 XV = {};
 XZ = {}; // xTuple Zombie. Used to help zombie within the context of these tests.
 
+// https://github.com/mikeal/request/issues/418#issuecomment-17149236
+process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
+
 var assert = require('assert'),
   zombie = require('zombie'),
-  URL = require('url'),
   _ = require('underscore');
 
 
@@ -100,23 +131,15 @@ Simplest possible usage:
       return;
     }
 
-    var parse = URL.parse;
-    URL.parse = function (url) {
-      if (_.isObject(url) && _.isString(url.href)) {
-        return parse(url.href);
-      }
-      else {
-        return parse(url);
-      }
-    };
 
-    zombie.visit(host, {debug: verboseMode}, function (e, browser) {
+    zombie.visit(host, {debug: verboseMode, runScripts: false}, function (e, browser) {
       if (e) {
-        //console.log("Zombie visit error: ", e);
+        console.log("Zombie visit error: ", e);
       }
       //
       // This is the login screen
       //
+      browser.runScripts = true;
       browser
         .fill('id', username)
         .fill('password', password)
index 0a6659c..3be3de5 100644 (file)
@@ -7,6 +7,8 @@ setTimeout:true, before:true, clearTimeout:true, exports:true, it:true, describe
 (function () {
   "use strict";
 
+  var assert = require("chai").assert;
+
   /**
     @class
     @alias Country
@@ -70,18 +72,44 @@ setTimeout:true, before:true, clearTimeout:true, exports:true, it:true, describe
     updatableField: "name"
   };
   var additionalTests = function () {
-    /**
-      @member -
-      @memberof Country.prototype
-      @description Length of Abbreviation field should not exceed 2, Currency Abbreviation
-      and Currency Number should not exceed 3 and Currency Number value should be an integer
-    */
-    it.skip("Abbreviation length should not exceed 2", function () {
-    });
-    it.skip("Length of Currency Abbreviation should not exceed 3", function () {
-    });
-    it.skip("Currency Number value should be an integer and its length should not" +
-    " exceed 3 ", function () {
+    describe("Country field validation", function () {
+      var countryModel;
+
+      beforeEach(function () {
+        countryModel = new XM.Country();
+        countryModel.initialize(null, {isNew: true});
+      });
+      /**
+        @member -
+        @memberof Country.prototype
+        @description Length of Abbreviation field should be 2, Currency Abbreviation
+        and Currency Number should be 3
+      */
+      it("Abbreviation length should be less than 2", function () {
+        countryModel.set("abbreviation", "A");
+        assert.isObject(countryModel.validate(countryModel.attributes));
+      });
+      it("Length of Currency Abbreviation should not be less than 3", function () {
+        countryModel.set("currencyAbbreviation", "AB");
+        assert.isObject(countryModel.validate(countryModel.attributes));
+      });
+      it("Currency Number length should not be less than 3", function () {
+        countryModel.set("currencyNumber", "AB");
+        assert.isObject(countryModel.validate(countryModel.attributes));
+      });
+
+      it("Abbreviation length should not exceed 2", function () {
+        countryModel.set("abbreviation", "ABC");
+        assert.isObject(countryModel.validate(countryModel.attributes));
+      });
+      it("Length of Currency Abbreviation should not exceed 3", function () {
+        countryModel.set("currencyAbbreviation", "ABCD");
+        assert.isObject(countryModel.validate(countryModel.attributes));
+      });
+      it("Currency Number length should not exceed 3", function () {
+        countryModel.set("currencyNumber", "ABCD");
+        assert.isObject(countryModel.validate(countryModel.attributes));
+      });
     });
   };
   exports.spec = spec;
index e674090..0a43b8e 100644 (file)
@@ -864,9 +864,9 @@ TODO deferred to later sprint:
         @description When currency or invoice date is changed outstanding credit should be
           recalculated.
       */
-      it.skip("When currency or invoice date is changed outstanding credit should be recalculated",
+      it.("When currency or invoice date is changed outstanding credit should be recalculated",
           function (done) {
-        // frustratingly nondeterministic
+
         this.timeout(9000);
         var outstandingCreditChanged = function () {
           if (invoiceModel.get("outstandingCredit")) {
index cfcdf28..bc3c845 100644 (file)
@@ -4,28 +4,75 @@
 /*global describe:true, it:true, XT:true, XM:true, XV:true, process:true,
   module:true, require:true, exports:true */
 
-  (function () {
+(function () {
   "use strict";
 
+  var assert = require("chai").assert,
+    smoke = require("../lib/smoke");
+
   /**
   Sites typically describe physical production and storage facilities. work centers, item sites, and site locations belong to sites.
   @class
   @alias Site
   **/
-  exports.spec = {
-    skipAll: true,
-    // XXX very awkward
-    recordType: "XM.Site"
+  var spec = {
+    // smoke is ran in the inventory site spec
+    skipSmoke: true,
+    recordType: "XM.Site",
+    collectionType: "XM.SiteCollection",
+    /**
+      @member -
+      @memberof Sites.prototype
+      @description The site collection is cached.
+    */
+    cacheName: "XM.sites",
+    listKind: "XV.SiteList",
+    instanceOf: "XM.Document",
+    extensions: [],
+    /**
+      @member -
+      @memberof Sites.prototype
+      @description Sites are lockable.
+    */
+    isLockable: true,
+    /**
+      @member -
+      @memberof Sites.prototype
+      @description The ID attribute is "code", which will not be automatically uppercased.
+    */
+    idAttribute: "code",
+    enforceUpperKey: false,
+    attributes: ["code", "address", "code", "comments", "contact", "description", "incoterms",
+      "isActive", "siteType", "taxZone"],
+    privileges: {
+      createUpdateDelete: "MaintainWarehouses",
+      view: true
+    },
+    createHash: {
+      isActive: true,
+      code: "NewSite" + Math.random(),
+      siteType: {name: "MFG"}
+    },
+    updatableField: "description"
   };
+
   var additionalTests = function () {
     /**
       @member Setup
       @memberof Site.prototype
-      @description Multiple Item Sites should not be allowed on Postbooks
+      @description Multiple Sites should not be allowed on Postbooks
     */
-    it.skip("Multiple Item Sites should not be allowed on Postbooks", function () {
+    it("Multiple Sites should not be allowed on Postbooks", function (done) {
+      if (!XT.extensions.inventory) {
+        assert.equal(XM.sites.length, 1);
+        smoke.navigateToList(XT.app, "XV.SiteList");
+        assert.isTrue(XT.app.$.postbooks.getActive().$.newButton.disabled);
+        return done();
+      }
+      done();
     });
-};
+  };
 
+  exports.spec = spec;
   exports.additionalTests = additionalTests;
-}());
\ No newline at end of file
+}());