+*.log
*.DS_Store
*.sw*
*~
language: node_js
node_js:
- - "0.8"
+ - "0.10"
install:
- "bash scripts/install_xtuple.sh -ipn"
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.
### 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)
+++ /dev/null
-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_
},
_didValidateSession: function (payload, callback) {
+ var coreVersion;
+
if (payload.code === 1) {
// If this is a valid session acquisition, go ahead
// and store the database config details in
this.setConfig(payload);
this.setDetails(payload.data);
- if (payload.version && XT.setVersion) {
+ if (payload.versions && XT.setVersion) {
// announce to the client what our version is, if we have
// a way of doing it.
- XT.setVersion(payload.version);
+
+ _.each(payload.versions, function (version, extensionName) {
+ // default to the core version (temp until all core extensions are in npm)
+ if (extensionName === "core") {
+ coreVersion = version;
+ extensionName = "";
+ } else if (version === "none") {
+ version = coreVersion;
+ }
+
+ var aboutVersionLabel = XT.app.$.postbooks.$.navigator.$.aboutVersion,
+ versionText = extensionName + " " + "_version".loc().toLowerCase() + " " + version;
+
+ if (aboutVersionLabel.getContent()) {
+ versionText = aboutVersionLabel.getContent() + "<br>" + versionText;
+ }
+
+ aboutVersionLabel.setContent(versionText);
+ });
}
// Start the client loading process.
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);
}
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;
+ }
});
};
XT.setVersion = function (version, qualifier) {
- // default to the core version
- version = version || XT.session.config.version;
-
- var aboutVersionLabel = XT.app.$.postbooks.$.navigator.$.aboutVersion,
- versionText = "_version".loc() + " " + version;
-
- if (qualifier) {
- versionText = ("_" + qualifier).loc() + " " + versionText;
- }
- if (aboutVersionLabel.getContent()) {
- versionText = aboutVersionLabel.getContent() + "<br>" + versionText;
- }
-
- aboutVersionLabel.setContent(versionText);
+ XT.log("XT.setVersion is now deprecated. The app now reads extension versions from " +
+ "package.json or manifest.js (" + qualifier + ")");
};
}());
{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"}
]}
]}
]}
]}
]
});
-
+
XV.registerModelList("XM.UserAccountRelation", "XV.UserAccountList");
// ..........................................................
{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}
]}
]}
]}
{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"}
]}
]
});
XV.registerModelWorkspace("XM.UserAccountRoleRelation", "XV.UserAccountRoleWorkspace");
XV.registerModelWorkspace("XM.UserAccountRoleListItem", "XV.UserAccountRoleWorkspace");
-
}());
"column": "cust_active"
}
},
+ {
+ "name": "customerType",
+ "toOne": {
+ "isNested": true,
+ "type": "CustomerType",
+ "column": "cust_custtype_id"
+ }
+ },
{
"name": "billingContact",
"toOne": {
"name": "name",
"attr": {
"type": "String",
- "column": "dept_name"
+ "column": "dept_name",
+ "required": true
}
}
],
"name": "name",
"attr": {
"type": "String",
- "column": "shift_name"
+ "column": "shift_name",
+ "required": true
}
}
],
"attr": {
"type": "String",
"column": "warehous_code",
- "isNaturalKey":true
+ "isNaturalKey":true,
+ "required": true
}
},
{
"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": {
-UPDATE pkghead SET pkghead_version = '4.6.0' WHERE pkghead_name = 'xt';
+UPDATE pkghead SET pkghead_version = '4.7.0Beta' WHERE pkghead_name = 'xt';
itemsite_location_comments,
itemsite_notes,
itemsite_perishable,
- itemsite_nnqoh,
itemsite_autoabcclass,
itemsite_ordergroup,
itemsite_disallowblankwip,
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),
"use strict";
XT.extensions.billing = {
- name: "billing",
- setVersion: function () {
- XT.setVersion("", XT.extensions.billing.name);
- }
+ name: "billing"
};
}());
-select xt.add_report_definition('XM.Invoice', 0, $${
+select xt.add_report_definition('XM.Invoice', 0, $${
"settings": {
"detailAttribute": "lineItems",
"defaultFontSize": 12,
},
{"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": [
(function () {
"use strict";
- XT.extensions.crm = {
- setVersion: function () {
- XT.setVersion("", "crm");
- }
- };
+ XT.extensions.crm = {};
}());
(function () {
"use strict";
- XT.extensions.oauth2 = {
- setVersion: function () {
- XT.setVersion("4.4.0", "oauth2");
- }
- };
+ XT.extensions.oauth2 = {};
}());
"_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",
(function () {
"use strict";
- XT.extensions.project = {
- setVersion: function () {
- XT.setVersion("", "project");
- }
- };
+ XT.extensions.project = {};
}());
(function () {
"use strict";
- XT.extensions.purchasing = {
- setVersion: function () {
- XT.setVersion("", "purchasing");
- }
- };
+ XT.extensions.purchasing = {};
}());
(function () {
"use strict";
- XT.extensions.sales = {
- setVersion: function () {
- XT.setVersion("", "sales");
- }
- };
+ XT.extensions.sales = {};
}());
"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"
]
}
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;
-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,
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;
-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
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
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;
WHERE (invcitem_invchead_id=pInvcheadid);
IF (pType IN ('T', 'X')) THEN
- SELECT SUM(tax) INTO _tax
+ SELECT COALESCE(SUM(tax), 0.0) INTO _tax
FROM (SELECT COALESCE(ROUND(SUM(taxdetail_tax), 2), 0.0) AS tax
FROM tax
JOIN calculateTaxDetailSummary('I', pInvcheadid, 'T')ON (taxdetail_tax_id=tax_id)
AND (coitem_status != 'X');
IF (pType IN ('T', 'B', 'X')) THEN
- SELECT SUM(tax) INTO _tax
+ SELECT COALESCE(SUM(tax), 0.0) INTO _tax
FROM (SELECT COALESCE(ROUND(SUM(taxdetail_tax), 2), 0.0) AS tax
FROM tax
JOIN calculateTaxDetailSummary('S', pCoheadid, 'T')ON (taxdetail_tax_id=tax_id)
-- 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;
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;
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
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);
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)
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;
-- 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;
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
*/
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
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);
-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;
-- 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;
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;
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;
_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;
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,
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,
_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,
RETURN _new.itemsite_id;
END;
-$$ LANGUAGE 'plpgsql';
\ No newline at end of file
+$$ LANGUAGE plpgsql;
\ No newline at end of file
-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;
BEGIN
- IF ( ( SELECT ( (itemsite_qtyonhand <> 0) OR (itemsite_nnqoh <> 0) )
+ IF ( ( SELECT (itemsite_qtyonhand <> 0)
FROM itemsite
WHERE (itemsite_id=pItemsiteid) ) ) THEN
RETURN -9;
RETURN 0;
END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
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;
-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;
-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;
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
RETURN _distCounter;
END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
-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;
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;
RETURN _distCounter;
END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION fetchNextCheckNumber(INTEGER) RETURNS INTEGER AS '
+CREATE OR REPLACE FUNCTION fetchNextCheckNumber(pBankaccntid 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
pBankaccntid ALIAS FOR $1;
_nextChkNumber INTEGER;
+ _checkheadid INTEGER;
BEGIN
FROM bankaccnt
WHERE (bankaccnt_id=pBankaccntid);
+ WHILE (TRUE) LOOP
+ SELECT checkhead_id INTO _checkheadid
+ FROM checkhead
+ WHERE (checkhead_number=_nextChkNumber)
+ AND (checkhead_bankaccnt_id=pBankaccntid);
+ IF (NOT FOUND) THEN
+ EXIT;
+ ELSE
+ _nextChkNumber := _nextChkNumber + 1;
+ END IF;
+ END LOOP;
+
UPDATE bankaccnt
SET bankaccnt_nextchknum = (bankaccnt_nextchknum + 1)
WHERE (bankaccnt_id=pBankaccntid);
RETURN _nextChkNumber;
END;
-' LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
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
--- /dev/null
+
+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';
+
--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
_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;
_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
_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;
_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,
_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;
-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;
( _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
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;
-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
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;
RETURN FALSE;
END;
-' LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
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;
-- 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
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
END IF;
END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
-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;
_itemloc RECORD;
_cntslip RECORD;
_origLocQty NUMERIC;
- _netable BOOLEAN;
_lsid INTEGER;
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)
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;
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
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
RETURN 0;
END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
(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,
--- /dev/null
+
+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;
-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;
--- /dev/null
+
+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;
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;
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
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
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
RETURN _invhistid;
END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION setNextCheckNumber(INTEGER, INTEGER) RETURNS BOOLEAN AS '
+CREATE OR REPLACE FUNCTION setNextCheckNumber(pBankaccntid INTEGER,
+ pNextCheckNumber 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
- pBankaccntid ALIAS FOR $1;
- pNextCheckNumber ALIAS FOR $2;
+ _nextChkNumber INTEGER;
+ _checkheadid INTEGER;
BEGIN
+ _nextChkNumber := pNextCheckNumber;
+
+ WHILE (TRUE) LOOP
+ SELECT checkhead_id INTO _checkheadid
+ FROM checkhead
+ WHERE (checkhead_number=_nextChkNumber)
+ AND (checkhead_bankaccnt_id=pBankaccntid);
+ IF (NOT FOUND) THEN
+ EXIT;
+ ELSE
+ _nextChkNumber := _nextChkNumber + 1;
+ END IF;
+ END LOOP;
+
UPDATE bankaccnt
- SET bankaccnt_nextchknum=pNextCheckNumber
+ SET bankaccnt_nextchknum=_nextChkNumber
WHERE (bankaccnt_id=pBankaccntid);
RETURN TRUE;
END;
-' LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
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 +
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)
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)
-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;
-- 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))
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
-- 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;
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);
RETURN pItemsiteid;
END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
-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;
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;
RETURN -1;
END;
-$$ LANGUAGE 'plpgsql';
+$$ LANGUAGE plpgsql;
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,
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,
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,
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,
--- /dev/null
+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');
--- /dev/null
+<!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>
--- /dev/null
+-- 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
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$$;
-- 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") ?>
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
-- 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") ?>
(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,
(coitem_price / coitem_price_invuomratio), 2) AS extpricebalance,
round((noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) * coitem_qty_invuomratio) *
(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,
+ 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)
-- CASE WHEN (qtyAvailable(itemsite_id, coitem_scheddate) < 0.0) THEN 'error'
'qty' AS qtyavailable_xtnumericrole,
'salesprice' AS coitem_price_xtnumericrole,
'salesprice' AS baseunitprice_xtnumericrole,
+ 'cost' AS coitem_unitcost_xtnumericrole,
'curr' AS extprice_xtnumericrole,
+ 'curr' AS extcost_xtnumericrole,
+ 'curr' AS margin_xtnumericrole,
+ 'percent' AS marginpercent_xtnumericrole,
'curr' AS baseextprice_xtnumericrole,
'curr' AS extpricebalance_xtnumericrole,
'curr' AS baseextpricebalance_xtnumericrole,
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT cohist_salesrep_id, salesrep_number, salesrep_name, cust_number, cust_name,
- cohist_ordernumber, cohist_invcnumber, cohist_invcdate, currAbbr,
+ cohist_ordernumber, cohist_orderdate, cohist_invcnumber, cohist_invcdate, currAbbr,
SUM(extprice) AS sumextprice,
SUM(cohist_commission) AS sumcommission,
SUM(baseextprice) AS sumbaseextprice,
SUM(basecommission) AS sumbasecommission,
+<? if exists("isReport") ?>
+ formatDate(cohist_orderdate) AS f_orderdate,
+ formatDate(cohist_invcdate) AS f_invcdate,
+ formatMoney(SUM(extprice)) AS f_sumextprice,
+ formatMoney(SUM(baseextprice)) AS f_sumbaseextprice,
+ formatMoney(SUM(cohist_commission)) AS f_sumcommission,
+ formatMoney(SUM(basecommission)) AS f_sumbasecommission,
+<? endif ?>
+ <? value("return") ?> AS cohist_invcdate_xtnullrole,
'curr' AS sumextprice_xtnumericrole,
'curr' AS sumcommission_xtnumericrole,
'curr' AS sumbaseextprice_xtnumericrole,
<? endif ?>
WHERE ((cohist_commission <> 0)
AND(cohist_invcdate BETWEEN <? value("startDate") ?> AND <? value("endDate") ?>)
- <? if exists("includeMisc") ?>
- AND (COALESCE(cohist_misc_type, '') <> 'T')
- AND (COALESCE(cohist_misc_type, '') <> 'F')
- <? endif ?>
<? if exists("salesrep_id") ?>
AND (cohist_salesrep_id=<? value("salesrep_id") ?>)
<? endif ?>
)
GROUP BY cohist_salesrep_id, salesrep_number, salesrep_name, cust_number, cust_name,
- cohist_ordernumber, cohist_invcnumber, cohist_invcdate, currAbbr
+ cohist_ordernumber, cohist_orderdate, cohist_invcnumber, cohist_invcdate, currAbbr
ORDER BY salesrep_number, cust_number, cohist_invcdate;
-- 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
- COALESCE(cohead_id,-1) AS cohead_id, cust_id, cohist_ponumber,
- cust_custtype_id, custtype_code,
- cohist_cust_id, SUM(extcost) AS extcost,
+SELECT cohead_id, cust_id, cohist_ponumber,
+ custtype_id, custtype_code,
+ cohist_cust_id, cohist_ordernumber,
+ cust_number, cust_name, currAbbr,
+ cohist_orderdate, cohist_invcdate,
+ CASE WHEN (COALESCE(cohist_invcnumber, '-1') IN ('', '-1')) THEN <? value("credit") ?>
+ ELSE cohist_invcnumber
+ END AS invoicenumber,
+ SUM(extprice) AS extprice,
+ SUM(baseextprice) AS baseextprice,
+ SUM(extcost) AS extcost,
+ SUM(margin) AS margin,
+ CASE WHEN (SUM(baseextprice) > 0.0) THEN
+ ROUND(SUM(margin) / SUM(baseextprice), 4)
+ ELSE 0.0
+ END AS marginpercent,
+<? if exists("isReport") ?>
+ formatDate(cohist_orderdate) AS f_orderdate,
+ formatDate(cohist_invcdate) AS f_invcdate,
+ formatMoney(SUM(extprice)) AS f_extprice,
+ formatMoney(SUM(baseextprice)) AS f_baseextprice,
+ formatMoney(SUM(extcost)) AS f_extcost,
+ formatMoney(SUM(margin)) AS f_margin,
+<? endif ?>
+ <? value("return") ?> AS cohist_invcdate_xtnullrole,
+ 'curr' AS extprice_xtnumericrole,
+ 'curr' AS baseextprice_xtnumericrole,
'curr' AS extcost_xtnumericrole,
+ 'curr' AS margin_xtnumericrole,
+ 'percent' AS marginpercent_xtnumericrole,
+ 0 AS baseextprice_xttotalrole,
0 AS extcost_xttotalrole,
- cohist_ordernumber,
- cust_number, cust_name, invoicenumber,
- cohist_orderdate, cohist_invcdate,
- SUM(baseextprice) AS extended,
- 'curr' AS extended_xtnumericrole,
- 0 AS extended_xttotalrole
-FROM saleshistory
- LEFT OUTER JOIN cohead ON (cohead_number=cohist_ordernumber)
-WHERE ((cohist_invcdate BETWEEN <? value("startDate") ?> AND <? value("endDate") ?>)
+ 0 AS margin_xttotalrole
+<? if exists("includeMisc") ?>
+ FROM saleshistorymisc
+<? else ?>
+ FROM saleshistory
+<? endif ?>
+WHERE ( (true)
+<? if exists("startDate") ?>
+ AND (cohist_invcdate >= <? value("startDate") ?>)
+<? endif ?>
+<? if exists("endDate") ?>
+ AND (cohist_invcdate <= <? value("endDate") ?>)
+<? endif ?>
+<? if exists("shipStartDate") ?>
+ AND (cohist_shipdate >= <? value("shipStartDate") ?>)
+<? endif ?>
+<? if exists("shipEndDate") ?>
+ AND (cohist_shipdate <= <? value("shipEndDate") ?>)
+<? endif ?>
<? if exists("cust_id") ?>
AND (cohist_cust_id=<? value("cust_id") ?>)
<? endif ?>
AND (cohist_shipto_id=<? value("shipto_id") ?>)
<? endif ?>
<? if exists("custtype_id") ?>
- AND (cust_custtype_id=<? value("custtype_id") ?>)
+ AND (custtype_id=<? value("custtype_id") ?>)
<? endif ?>
<? if exists("custtype_pattern") ?>
AND (custtype_code ~ <? value("custtype_pattern") ?>)
AND (custgrp_name ~ <? value("custgrp_pattern") ?>) )) )
<? endif ?>
<? if exists("warehous_id") ?>
- AND (itemsite_warehous_id=<? value("warehous_id") ?>)
+ AND (warehous_id=<? value("warehous_id") ?>)
<? endif ?>
<? if exists("item_id") ?>
- AND (itemsite_item_id=<? value("item_id") ?>)
+ AND (item_id=<? value("item_id") ?>)
<? endif ?>
<? if exists("prodcat_id") ?>
- AND (item_prodcat_id=<? value("prodcat_id") ?>)
+ AND (prodcat_id=<? value("prodcat_id") ?>)
<? endif ?>
<? if exists("prodcat_pattern") ?>
- AND (item_prodcat_id IN (SELECT prodcat_id
- FROM prodcat
- WHERE (prodcat_code ~ <? value("prodcat_pattern") ?>)))
+ AND (prodcat_id IN (SELECT prodcat_id
+ FROM prodcat
+ WHERE (prodcat_code ~ <? value("prodcat_pattern") ?>)))
<? endif ?>
<? if exists("salesrep_id") ?>
AND (cohist_salesrep_id=<? value("salesrep_id") ?>)
+<? endif ?>
+<? if exists("shipzone_id") ?>
+ AND (cohist_shipzone_id=<? value("shipzone_id") ?>)
+<? endif ?>
+<? if exists("saletype_id") ?>
+ AND (cohist_saletype_id=<? value("saletype_id") ?>)
<? endif ?>
)
-GROUP BY cohead_id, cust_id,cust_number,cust_custtype_id,cohist_cust_id,custtype_code,
- cust_name,cohist_ordernumber, cohist_ponumber,
- invoicenumber,cohist_orderdate, cohist_invcdate
+GROUP BY cohead_id, cust_id, cust_number, custtype_id,
+ cohist_cust_id, custtype_code, currAbbr,
+ cust_name, cohist_ordernumber, cohist_ponumber,
+ cohist_invcnumber, cohist_orderdate, cohist_invcdate
ORDER BY cohist_invcdate, cohist_orderdate;
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
'' 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,
-- 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;
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
)
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,
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") ?>
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)
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 ?>
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,
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,
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,
itemsite_warrpurc, NULL AS itemloc_warrpurc,
NULL AS locationname,
NULL AS netable,
+ NULL AS usable,
NULL AS lotserial,
NULL AS expiration,
NULL AS warranty,
invchead_invcnumber AS docnumber,
findCustomerForm(cust_id, 'I') AS reportname,
<? endif ?>
+ CASE WHEN (calcInvoiceAmt(invchead_id,'S') != 0.0)
+ THEN calcInvoiceAmt(invchead_id,'M')
+ ELSE 0.0
+ END AS margin,
CASE WHEN (calcInvoiceAmt(invchead_id,'S') != 0.0)
THEN (calcInvoiceAmt(invchead_id,'M') / calcInvoiceAmt(invchead_id,'S'))
ELSE 1.0
END AS marginpercent,
'percent' AS marginpercent_xtnumericrole,
+ 'curr' AS margin_xtnumericrole,
'curr' AS extprice_xtnumericrole,
'curr' AS balance_xtnumericrole,
CASE WHEN (aropen_id IS NULL) THEN 'Unposted' END AS balance_qtdisplayrole
-- 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") ?>,
<? endforeach ?>
firstline(cohead_ordercomments) AS notes,
calcSalesOrderAmt(cohead_id) AS ordertotal,
+ CASE WHEN (calcSalesOrderAmt(cohead_id,'S') != 0.0)
+ THEN calcSalesOrderAmt(cohead_id,'M')
+ ELSE 0.0
+ END AS ordermargin,
CASE WHEN (calcSalesOrderAmt(cohead_id,'S') != 0.0)
THEN (calcSalesOrderAmt(cohead_id,'M') / calcSalesOrderAmt(cohead_id,'S'))
ELSE 1.0
END AS ordermarginpercent,
'percent' AS ordermarginpercent_xtnumericrole,
- 'extprice' AS ordertotal_xtnumericrole
+ 'extprice' AS ordertotal_xtnumericrole,
+ 'extprice' AS ordermargin_xtnumericrole
FROM cohead
JOIN custinfo ON (cohead_cust_id=cust_id)
JOIN custtype ON (cust_custtype_id=custtype_id)
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") ?>),
((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
<? if exists("id") ?>
AND (prj_id=<? value("id") ?>)
<? endif ?>
-<? literal("charClause") ?>
-<? if exists("prjtype_id") ?>
- AND (prjtype_id = <? value("prjtype_id") ?>)
+<? if exists("prj_id") ?>
+ AND (prj_id=<? value("prj_id") ?>)
+<? endif ?>
+<? if exists("project_task") ?>
+ AND prj_id IN (SELECT DISTINCT prjtask_prj_id FROM prjtask where ((prjtask_number ~* <? value("project_task") ?>)
+ OR (prjtask_name ~* <? value("project_task") ?>)
+ OR (prjtask_descrip ~* <? value("project_task") ?>)))
+<? endif ?>
+<? if exists("cohead_id") ?>
+ AND prj_id IN (SELECT cohead_prj_id FROM cohead where cohead_id=<? value("cohead_id") ?>)
<? endif ?>
+<? if exists("wo_id") ?>
+ AND prj_id IN (SELECT wo_prj_id FROM wo WHERE wo_id=<? value("wo_id") ?>)
+<? endif ?>
+<? if exists("pohead_id") ?>
+ AND prj_id IN (SELECT poitem_prj_id FROM pohead JOIN poitem ON (pohead_id=poitem_pohead_id)
+ WHERE pohead_id=<? value("pohead_id") ?>)
+<? endif ?>
+<? literal("charClause") ?>
ORDER BY prj_number;
\ No newline at end of file
-- 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)
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'
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'
<? 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 (
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
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
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
<? 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
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,
<? 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
-- 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 cohist.*,
- CASE WHEN (cohist_invcnumber='-1') THEN <? value("credit") ?>
+SELECT *,
+ CASE WHEN (COALESCE(cohist_invcnumber, '-1') IN ('', '-1')) THEN <? value("credit") ?>
ELSE cohist_invcnumber
END AS invoicenumber,
- cust_number, cust_name, salesrep_name,
- saletype_code, shipzone_name,
- item_id, COALESCE(item_number, cohist_misc_descrip) AS item_number,
- item_descrip1, (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
- warehous_code,
- currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate) AS baseunitprice,
- round((cohist_qtyshipped * cohist_unitprice), 2) AS extprice,
- round((cohist_qtyshipped * currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate)), 2) AS baseextprice,
- round((cohist_qtyshipped * cohist_unitcost), 4) AS extcost,
- currtobase(cohist_curr_id, cohist_commission, cohist_invcdate) AS basecommission,
<? if exists("isReport") ?>
+ formatDate(cohist_orderdate) AS f_orderdate,
formatDate(cohist_invcdate) AS f_invcdate,
formatQty(cohist_qtyshipped) AS f_qtyshipped,
formatBoolYN(cohist_commissionpaid) AS f_commissionpaid,
- formatSalesPrice(currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate)) AS f_baseunitprice,
- formatMoney(round((cohist_qtyshipped * cohist_unitprice), 2)) AS f_extprice,
- formatMoney(round((cohist_qtyshipped * currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate)), 2)) AS f_baseextprice,
- formatMoney(round((cohist_qtyshipped * cohist_unitcost), 4)) AS f_extcost,
- formatMoney(currtobase(cohist_curr_id, cohist_commission, cohist_invcdate)) AS f_basecommission,
+ formatSalesPrice(baseunitprice) AS f_baseunitprice,
+ formatMoney(extprice) AS f_extprice,
+ formatMoney(baseextprice) AS f_baseextprice,
+ formatMoney(extcost) AS f_extcost,
+ formatMoney(margin) AS f_margin,
+ formatPrcnt(marginpercent) AS f_marginpercent,
+ formatMoney(basecommission) AS f_basecommission,
<? endif ?>
- currConcat(cohist_curr_id) AS currAbbr,
<? value("return") ?> AS cohist_invcdate_xtnullrole,
- 'qty' AS cohist_qtyshipped_xtnumericrole,
- 'salesprice' AS cohist_unitprice_xtnumericrole,
- 'salesprice' AS baseunitprice_xtnumericrole,
- 'curr' AS extprice_xtnumericrole,
- 'curr' AS baseextprice_xtnumericrole,
- 'cost' AS cohist_unitcost_xtnumericrole,
- 'curr' AS extcost_xtnumericrole,
- 'curr' AS cohist_commission_xtnumericrole,
- 'curr' AS basecommission_xtnumericrole,
0 AS cohist_qtyshipped_xttotalrole,
0 AS baseextprice_xttotalrole,
0 AS extcost_xttotalrole,
+ 0 AS margin_xttotalrole,
0 AS basecommission_xttotalrole
- FROM cohist JOIN custinfo ON (cust_id=cohist_cust_id)
- JOIN salesrep ON (salesrep_id=cohist_salesrep_id)
- LEFT OUTER JOIN saletype ON (saletype_id=cohist_saletype_id)
- LEFT OUTER JOIN shipzone ON (shipzone_id=cohist_shipzone_id)
<? if exists("includeMisc") ?>
- LEFT OUTER JOIN itemsite ON (itemsite_id=cohist_itemsite_id)
- LEFT OUTER JOIN site() ON (warehous_id=itemsite_warehous_id)
- LEFT OUTER JOIN item ON (item_id=itemsite_item_id)
+ FROM saleshistorymisc
<? else ?>
- JOIN itemsite ON (itemsite_id=cohist_itemsite_id)
- JOIN site() ON (warehous_id=itemsite_warehous_id)
- JOIN item ON (item_id=itemsite_item_id)
-<? endif ?>
-<? if exists("cohead_id") ?>
- JOIN cohead ON (cohead_number=cohist_ordernumber)
+ FROM saleshistory
<? endif ?>
WHERE ( (true)
-<? if exists("includeMisc") ?>
- AND (COALESCE(cohist_misc_type, '') <> 'F')
- AND (COALESCE(cohist_misc_type, '') <> 'T')
-<? endif ?>
<? if exists("startDate") ?>
AND (cohist_invcdate >= <? value("startDate") ?>)
<? endif ?>
AND (cohist_cust_id=<? value("cust_id") ?>)
<? endif ?>
<? if exists("custtype_id") ?>
- AND (cust_custtype_id=<? value("custtype_id") ?>)
+ AND (custtype_id=<? value("custtype_id") ?>)
<? elseif exists("custtype_pattern") ?>
- AND (cust_custtype_id IN (SELECT DISTINCT custtype_id
- FROM custtype
- WHERE (custtype_code ~ <? value("custtype_pattern") ?>)))
+ AND (custtype_id IN (SELECT DISTINCT custtype_id
+ FROM custtype
+ WHERE (custtype_code ~ <? value("custtype_pattern") ?>)))
<? endif ?>
<? if exists("by_custgrp") ?>
AND (cust_id IN (SELECT DISTINCT custgrpitem_cust_id
<? endif ?>
<? if exists("item_id") ?>
- AND (itemsite_item_id=<? value("item_id") ?>)
+ AND (item_id=<? value("item_id") ?>)
<? endif ?>
<? if exists("prodcat_id") ?>
- AND (item_prodcat_id=<? value("prodcat_id") ?>)
+ AND (prodcat_id=<? value("prodcat_id") ?>)
<? endif ?>
<? if exists("prodcat_pattern") ?>
- AND (item_prodcat_id IN (SELECT DISTINCT prodcat_id
- FROM prodcat
- WHERE (prodcat_code ~ <? value("prodcat_pattern") ?>)))
+ AND (prodcat_id IN (SELECT DISTINCT prodcat_id
+ FROM prodcat
+ WHERE (prodcat_code ~ <? value("prodcat_pattern") ?>)))
<? endif ?>
<? if exists("warehous_id") ?>
- AND (itemsite_warehous_id=<? value("warehous_id") ?>)
+ AND (warehous_id=<? value("warehous_id") ?>)
<? endif ?>
<? if exists("shipzone_id") ?>
AND (cohist_shipzone_id=<? value("shipzone_id") ?>)
AND (cohead_id=<? value("cohead_id") ?>)
<? endif ?>
)
-ORDER BY cohist_invcdate, item_number;
+ORDER BY cohist_invcdate, itemnumber;
ELSE 1
END AS xtindentrole,
spplytype, ordrnumbr,
- itemsite_qtyonhand,
- 'qty' AS itemsite_qtyonhand_xtnumericrole
+ availableqoh,
+ 'qty' AS availableqoh_xtnumericrole
<? if exists("includeReservations") ?>
,
reserved,
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)
-- 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,
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,
<? 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 ?>
cust_number, cohist_cust_id AS cust_number_xtidrole, cust_name,
<? endif ?>
<? if exists("byCustomerType") ?>
- custtype_code, cust_custtype_id AS custtype_code_xtidrole,
+ custtype_code, custtype_id AS custtype_code_xtidrole,
<? endif ?>
<? if exists("byItem") ?>
item_number, item_id AS item_number_xtidrole, itemdescription,
<? endif ?>
<? if exists("bySalesRep") ?>
- salesrep_number, cohist_salesrep_id AS salesrep_number_xtidrole, salesrep_name,
+ salesrep_number, salesrep_id AS salesrep_number_xtidrole, salesrep_name,
<? endif ?>
<? if exists("byShippingZone") ?>
shipzone_name, shipzone_id AS shipzone_name_xtidrole,
<? endif ?>
<? if exists("bySite") ?>
- warehous_code, itemsite_warehous_id AS warehous_code_xtidrole,
+ warehous_code, warehous_id AS warehous_code_xtidrole,
<? endif ?>
<? if exists("byCurrency") ?>
currAbbr,
'curr' AS totalsales_xtnumericrole,
0 AS totalunits_xttotalrole,
0 AS totalsales_xttotalrole
-FROM saleshistory
-WHERE ((COALESCE(cohist_misc_type, '') <> 'F')
- AND (COALESCE(cohist_misc_type, '') <> 'T')
+FROM saleshistorymisc
+WHERE ( (TRUE)
<? if exists("startDate") ?>
AND (cohist_invcdate >= <? value("startDate") ?>)
<? endif ?>
<? endif ?>
<? if exists("warehous_id") ?>
- AND (itemsite_warehous_id=<? value("warehous_id") ?>)
+ AND (warehous_id=<? value("warehous_id") ?>)
<? endif ?>
<? if exists("item_id") ?>
- AND (itemsite_item_id=<? value("item_id") ?>)
+ AND (item_id=<? value("item_id") ?>)
<? endif ?>
<? if exists("cust_id") ?>
<? endif ?>
<? if exists("salesrep_id") ?>
- AND (cohist_salesrep_id=<? value("salesrep_id") ?>)
+ AND (salesrep_id=<? value("salesrep_id") ?>)
<? endif ?>
<? if exists("prodcat_id") ?>
- AND (item_prodcat_id=<? value("prodcat_id") ?>)
+ AND (prodcat_id=<? value("prodcat_id") ?>)
<? endif ?>
<? if exists("prodcat_pattern") ?>
<? endif ?>
<? if exists("custtype_id") ?>
- AND (cust_custtype_id=<? value("custtype_id") ?>)
+ AND (custtype_id=<? value("custtype_id") ?>)
<? endif ?>
<? if exists("custtype_pattern") ?>
)
GROUP BY dummy
<? if exists("bySalesRep") ?>
- , cohist_salesrep_id, salesrep_number, salesrep_name
+ , salesrep_id, salesrep_number, salesrep_name
<? endif ?>
<? if exists("byShippingZone") ?>
, shipzone_id, shipzone_name, shipzone_descrip
, cohist_cust_id, cust_number, cust_name
<? endif ?>
<? if exists("byCustomerType") ?>
- , cust_custtype_id, custtype_code, custtype_descrip
+ , custtype_id, custtype_code, custtype_descrip
<? endif ?>
<? if exists("byItem") ?>
, item_id, item_number, itemdescription
<? endif ?>
<? if exists("bySite") ?>
- , itemsite_warehous_id, warehous_code, warehous_descrip
+ , warehous_id, warehous_code, warehous_descrip
<? endif ?>
<? if exists("byCurrency") ?>
, cust_curr_id, currAbbr
(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") ?>
-SELECT setMetric('ServerVersion', '4.6.0');
+-- 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');
<title>Brief Earned Commissions</title>
<name>BriefEarnedCommissions</name>
<description></description>
+ <grid>
+ <snap/>
+ <show/>
+ <x>0.05</x>
+ <y>0.05</y>
+ </grid>
<size>Letter</size>
<portrait/>
<topmargin>50</topmargin>
formatDate(<? value("startDate") ?>) AS startdate,
formatDate(<? value("endDate") ?>) AS enddate;</sql>
</querysource>
- <querysource>
+ <querysource loadFromDb="true">
<name>detail</name>
- <sql>SELECT cohist_salesrep_id, salesrep_number, salesrep_name, cust_number, cust_name,
- cohist_ordernumber, cohist_invcnumber, formatDate(cohist_invcdate) AS f_invcdate, currAbbr,
- formatMoney(SUM(baseextprice)) AS f_extprice,
- formatMoney(SUM(basecommission)) AS f_commission,
- SUM(baseextprice) AS extprice,
- SUM(basecommission) AS commission
-<? if exists("includeMisc") ?>
-FROM saleshistorymisc
-<? else ?>
-FROM saleshistory
-<? endif ?>
-WHERE ( (cohist_commission <> 0)
- AND (cohist_invcdate BETWEEN <? value("startDate") ?> AND <? value("endDate") ?>)
-
-<? if exists("includeMisc") ?>
- AND (COALESCE(cohist_misc_type, '') <> 'T')
- AND (COALESCE(cohist_misc_type, '') <> 'F')
-<? endif ?>
-
-<? if exists("salesrep_id") ?>
- AND (cohist_salesrep_id=<? value("salesrep_id") ?>)
-<? endif ?>
-)
-GROUP BY cohist_salesrep_id, salesrep_number, salesrep_name, cust_number, cust_name,
- cohist_ordernumber, cohist_invcnumber, cohist_invcdate, currAbbr
-ORDER BY salesrep_number, cust_number, cohist_invcdate
-</sql>
+ <mqlgroup>briefEarnedCommission</mqlgroup>
+ <mqlname>detail</mqlname>
</querysource>
<rpthead>
<height>221</height>
<vcenter/>
<data>
<query>detail</query>
- <column>f_extprice</column>
+ <column>f_sumbaseextprice</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>f_commission</column>
+ <column>f_sumbasecommission</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>extprice</column>
+ <column>sumbaseextprice</column>
</data>
<format builtin="true">money</format>
<tracktotal/>
<vcenter/>
<data>
<query>detail</query>
- <column>commission</column>
+ <column>sumbasecommission</column>
</data>
<format builtin="true">money</format>
<tracktotal/>
<? endif ?>
AS docnumber; </sql>
</querysource>
- <querysource>
+ <querysource loadFromDb="true">
<name>detail</name>
- <sql>SELECT cohist_ordernumber AS sonumber,
- cohist_invcnumber AS invnumber,
- formatDate(cohist_orderdate) AS orddate,
- formatDate(cohist_invcdate, 'Return') AS shipdate,
- SUM(round(cohist_qtyshipped * currtobase(cohist_curr_id,cohist_unitprice,cohist_invcdate),2)) as extended,
- formatMoney(SUM(round(cohist_qtyshipped * currtobase(cohist_curr_id,cohist_unitprice,cohist_invcdate),2))) as f_total,
- SUM(round(cohist_qtyshipped * currtobase(cohist_curr_id,cohist_unitprice,cohist_invcdate),2)) as total
-FROM saleshistory
- LEFT OUTER JOIN cohead ON (cohead_number=cohist_ordernumber)
-WHERE ((cohist_invcdate BETWEEN <? value("startDate") ?> AND <? value("endDate") ?>)
-<? if exists("cust_id") ?>
- AND (cohist_cust_id=<? value("cust_id") ?>)
-<? endif ?>
-<? if exists("shipto_id") ?>
- AND (cohist_shipto_id=<? value("shipto_id") ?>)
-<? endif ?>
-<? if exists("custtype_id") ?>
- AND (cust_custtype_id=<? value("custtype_id") ?>)
-<? endif ?>
-<? if exists("custtype_pattern") ?>
- AND (custtype_code ~ <? value("custtype_pattern") ?>)
-<? endif ?>
-<? if exists("custgrp_id") ?>
- AND (cust_id IN (SELECT DISTINCT custgrpitem_cust_id
- FROM custgrpitem
- WHERE (custgrpitem_custgrp_id=<? value("custgrp_id") ?>)))
-<? endif ?>
-<? if exists("custgrp_pattern") ?>
- AND (cust_id IN (SELECT DISTINCT custgrpitem_cust_id
- FROM custgrp, custgrpitem
- WHERE ( (custgrpitem_custgrp_id=custgrp_id)
- AND (custgrp_name ~ <? value("custgrp_pattern") ?>) )) )
-<? endif ?>
-<? if exists("warehous_id") ?>
- AND (itemsite_warehous_id=<? value("warehous_id") ?>)
-<? endif ?>
-<? if exists("item_id") ?>
- AND (itemsite_item_id=<? value("item_id") ?>)
-<? endif ?>
-<? if exists("prodcat_id") ?>
- AND (item_prodcat_id=<? value("prodcat_id") ?>)
-<? endif ?>
-<? if exists("prodcat_pattern") ?>
- AND (item_prodcat_id IN (SELECT prodcat_id
- FROM prodcat
- WHERE (prodcat_code ~ <? value("prodcat_pattern") ?>)))
-<? endif ?>
-<? if exists("salesrep_id") ?>
- AND (cohist_salesrep_id=<? value("salesrep_id") ?>)
-<? endif ?>
- )
-GROUP BY cohead_id, cust_id,cust_number,cust_custtype_id,cohist_cust_id,custtype_code,
- cust_name,cohist_ordernumber, cohist_ponumber,
- cohist_invcnumber,cohist_orderdate, cohist_invcdate
-ORDER BY cohist_invcdate, cohist_orderdate;</sql>
+ <mqlgroup>briefSalesHistory</mqlgroup>
+ <mqlname>detail</mqlname>
</querysource>
<rpthead>
<height>221</height>
</font>
<hcenter/>
<vcenter/>
- <string>Ship Date</string>
+ <string>Invc. Date</string>
</label>
<label>
<rect>
<vcenter/>
<data>
<query>detail</query>
- <column>sonumber</column>
+ <column>cohist_ordernumber</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>invnumber</column>
+ <column>invoicenumber</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>f_total</column>
+ <column>f_baseextprice</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>shipdate</column>
+ <column>f_invcdate</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>orddate</column>
+ <column>f_orderdate</column>
</data>
</field>
</detail>
<vcenter/>
<data>
<query>detail</query>
- <column>total</column>
+ <column>baseextprice</column>
</data>
<format builtin="true">money</format>
<tracktotal/>
<title>Earned Commissions</title>
<name>EarnedCommissions</name>
<description></description>
+ <grid>
+ <snap/>
+ <show/>
+ <x>0.05</x>
+ <y>0.05</y>
+ </grid>
<size>Letter</size>
<portrait/>
<topmargin>50</topmargin>
formatDate(<? value("startDate") ?>) AS startdate,
formatDate(<? value("endDate") ?>) AS enddate;</sql>
</querysource>
- <querysource loadFromDb="true" >
+ <querysource loadFromDb="true">
<name>detail</name>
<mqlgroup>salesHistory</mqlgroup>
<mqlname>detail</mqlname>
<vcenter/>
<data>
<query>detail</query>
- <column>item_number</column>
+ <column>itemnumber</column>
</data>
</field>
<field>
<query>detail</query>
<column>baseextprice</column>
</data>
- <tracktotal builtin="true" >qty</tracktotal>
+ <format builtin="true">qty</format>
+ <tracktotal/>
</field>
<field>
<rect>
<query>detail</query>
<column>basecommission</column>
</data>
- <tracktotal builtin="true" >qty</tracktotal>
+ <format builtin="true">qty</format>
+ <tracktotal/>
</field>
</rptfoot>
</report>
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,
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,
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))))
<? endif ?>
WHERE((coitem_cohead_id=cohead_id)
AND (cohead_cust_id=cust_id)
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,
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))))
<? endif ?>
WHERE ( (coitem_cohead_id=cohead_id)
AND (coitem_itemsite_id=itemsite_id)
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,
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
<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, <? value("lookAheadDays") ?>, <? if exists("includePlannedOrder") ?>true<? else ?>false<? endif ?>) AS reorderdate, itemsite_qtyonhand,
+ reorderDate(itemsite_id, <? value("lookAheadDays") ?>, <? if exists("includePlannedOrder") ?>true<? else ?>false<? 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)
<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
<bottommargin>50</bottommargin>
<rightmargin>50</rightmargin>
<leftmargin>50</leftmargin>
- <querysource>
+ <querysource loadFromDb="true">
<name>detail</name>
- <sql>SELECT cohist_ordernumber AS sonumber,
- cohist_invcnumber AS invnumber,
- formatDate(cohist_orderdate) AS orddate,
- formatDate(cohist_invcdate, 'Return') AS invcdate,
- item_number, item_descrip1, item_descrip2,
- formatQty(cohist_qtyshipped) AS shipped,
- <? if exists("showPrices") ?>
- formatPrice(currtobase(cohist_curr_id,cohist_unitprice,cohist_invcdate)) AS unitprice,
- formatMoney(round(cohist_qtyshipped * currtobase(cohist_curr_id,cohist_unitprice,cohist_invcdate),2)) AS f_total,
- <? else ?>
- '' AS unitprice,
- '' AS f_total,
- <? endif ?>
- round(cohist_qtyshipped * currtobase(cohist_curr_id,cohist_unitprice,cohist_invcdate),2) AS total
- FROM cohist JOIN custinfo ON (cust_id=cohist_cust_id)
- JOIN salesrep ON (salesrep_id=cohist_salesrep_id)
-<? if exists("includeMisc") ?>
- LEFT OUTER JOIN itemsite ON (itemsite_id=cohist_itemsite_id)
- LEFT OUTER JOIN site() ON (warehous_id=itemsite_warehous_id)
- LEFT OUTER JOIN item ON (item_id=itemsite_item_id)
-<? else ?>
- JOIN itemsite ON (itemsite_id=cohist_itemsite_id)
- JOIN site() ON (warehous_id=itemsite_warehous_id)
- JOIN item ON (item_id=itemsite_item_id)
-<? endif ?>
-<? if exists("cohead_id") ?>
- JOIN cohead ON (cohead_number=cohist_ordernumber)
-<? endif ?>
-WHERE ( (true)
-<? if exists("includeMisc") ?>
- AND (COALESCE(cohist_misc_type, '') <> 'F')
- AND (COALESCE(cohist_misc_type, '') <> 'T')
-<? endif ?>
-<? if exists("startDate") ?>
- AND (cohist_invcdate >= <? value("startDate") ?>)
-<? endif ?>
-<? if exists("endDate") ?>
- AND (cohist_invcdate <= <? value("endDate") ?>)
-<? endif ?>
-<? if exists("shipStartDate") ?>
- AND (cohist_shipdate >= <? value("shipStartDate") ?>)
-<? endif ?>
-<? if exists("shipEndDate") ?>
- AND (cohist_shipdate <= <? value("shipEndDate") ?>)
-<? endif ?>
-<? if exists("salesrep_id") ?>
- AND (cohist_salesrep_id=<? value("salesrep_id") ?>)
-<? endif ?>
-<? if exists("shipto_id") ?>
- AND (cohist_shipto_id=<? value("shipto_id") ?>)
-<? endif ?>
-<? if exists("billToName") ?>
- AND (UPPER(cohist_billtoname) ~ UPPER(<? value("billToName") ?>))
-<? endif ?>
-<? if exists("cust_id") ?>
- AND (cohist_cust_id=<? value("cust_id") ?>)
-<? endif ?>
-<? if exists("custtype_id") ?>
- AND (cust_custtype_id=<? value("custtype_id") ?>)
-<? elseif exists("custtype_pattern") ?>
- AND (cust_custtype_id IN (SELECT DISTINCT custtype_id
- FROM custtype
- WHERE (custtype_code ~ <? value("custtype_pattern") ?>)))
-<? endif ?>
-<? if exists("by_custgrp" ?>
- AND (cust_id IN (SELECT DISTINCT custgrpitem_cust_id
- FROM custgrpitem))
-<? endif ?>
-<? if exists("custgrp_id") ?>
- AND (cust_id IN (SELECT DISTINCT custgrpitem_cust_id
- FROM custgrpitem
- WHERE (custgrpitem_custgrp_id=<? value("custgrp_id") ?>)))
-<? endif ?>
-<? if exists("custgrp_pattern") ?>
- AND (cust_id IN (SELECT DISTINCT custgrpitem_cust_id
- FROM custgrp, custgrpitem
- WHERE ( (custgrpitem_custgrp_id=custgrp_id)
- AND (custgrp_name ~ <? value("custgrp_pattern") ?>) )) )
-<? endif ?>
-
-<? if exists("item_id") ?>
- AND (itemsite_item_id=<? value("item_id") ?>)
-<? endif ?>
-<? if exists("prodcat_id") ?>
- AND (item_prodcat_id=<? value("prodcat_id") ?>)
-<? endif ?>
-<? if exists("prodcat_pattern") ?>
- AND (item_prodcat_id IN (SELECT DISTINCT prodcat_id
- FROM prodcat
- WHERE (prodcat_code ~ <? value("prodcat_pattern") ?>)))
-<? endif ?>
-
-<? if exists("warehous_id") ?>
- AND (itemsite_warehous_id=<? value("warehous_id") ?>)
-<? endif ?>
-<? if exists("shipzone_id") ?>
- AND (cohist_shipzone_id=<? value("shipzone_id") ?>)
-<? endif ?>
-<? if exists("saletype_id") ?>
- AND (cohist_saletype_id=<? value("saletype_id") ?>)
-<? endif ?>
-<? if exists("cohead_id") ?>
- AND (cohead_id=<? value("cohead_id") ?>)
-<? endif ?>
- )
-ORDER BY cohist_invcdate, item_number</sql>
+ <mqlgroup>salesHistory</mqlgroup>
+ <mqlname>detail</mqlname>
</querysource>
<querysource>
<name>head</name>
</pghead>
<section>
<name>detail</name>
+ <group>
+ <name>total</name>
+ <column></column>
+ <foot>
+ <height>39</height>
+ <field>
+ <rect>
+ <x>660</x>
+ <y>9</y>
+ <width>80</width>
+ <height>15</height>
+ </rect>
+ <font>
+ <face>Arial</face>
+ <size>8</size>
+ <weight>bold</weight>
+ </font>
+ <right/>
+ <vcenter/>
+ <data>
+ <query>detail</query>
+ <column>baseextprice</column>
+ </data>
+ <format builtin="true">money</format>
+ <tracktotal/>
+ </field>
+ <label>
+ <rect>
+ <x>570</x>
+ <y>9</y>
+ <width>80</width>
+ <height>15</height>
+ </rect>
+ <font>
+ <face>Arial</face>
+ <size>8</size>
+ <weight>normal</weight>
+ </font>
+ <right/>
+ <vcenter/>
+ <string>Total Sales:</string>
+ </label>
+ </foot>
+ </group>
<detail>
<key>
<query>detail</query>
<vcenter/>
<data>
<query>detail</query>
- <column>sonumber</column>
+ <column>cohist_ordernumber</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>unitprice</column>
+ <column>f_baseunitprice</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>orddate</column>
+ <column>f_orderdate</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>shipped</column>
+ <column>f_qtyshipped</column>
</data>
</field>
<line>
<vcenter/>
<data>
<query>detail</query>
- <column>invcdate</column>
+ <column>f_invcdate</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>item_number</column>
+ <column>itemnumber</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>f_total</column>
+ <column>f_baseextprice</column>
</data>
</field>
<field>
<vcenter/>
<data>
<query>detail</query>
- <column>invnumber</column>
+ <column>invoicenumber</column>
</data>
</field>
</detail>
</section>
- <section>
- <name>total</name>
- <detail>
- <key>
- <query>showPrices</query>
- </key>
- <height>16</height>
- <field>
- <rect>
- <x>665</x>
- <y>0</y>
- <width>80</width>
- <height>15</height>
- </rect>
- <font>
- <face>Arial</face>
- <size>8</size>
- <weight>bold</weight>
- </font>
- <right/>
- <vcenter/>
- <data>
- <query>detail</query>
- <column>total</column>
- </data>
- <format builtin="true">money</format>
- <tracktotal/>
- </field>
- <label>
- <rect>
- <x>575</x>
- <y>0</y>
- <width>80</width>
- <height>15</height>
- </rect>
- <font>
- <face>Arial</face>
- <size>8</size>
- <weight>normal</weight>
- </font>
- <right/>
- <vcenter/>
- <string>Total Sales:</string>
- </label>
- </detail>
- </section>
<pgfoot>
<height>16</height>
<label>
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,
<? if exists("byDays") ?>
formatQty(qtyAllocated(sub.itemsite_id, <? value("byDays") ?>)) AS f_allocated,
formatQty(qtyOrdered(sub.itemsite_id, <? value("byDays") ?>)) AS f_ordered,
- formatQty(sub.itemsite_qtyonhand + qtyOrdered(sub.itemsite_id, <? value("byDays") ?>) - qtyAllocated(sub.itemsite_id, <? value("byDays") ?>)) as f_avail
+ formatQty(qtyAvailable(sub.itemsite_id) + qtyOrdered(sub.itemsite_id, <? value("byDays") ?>) - qtyAllocated(sub.itemsite_id, <? value("byDays") ?>)) as f_avail
<? elseif exists("byDate") ?>
formatQty(qtyAllocated(sub.itemsite_id, (<? value("byDate") ?> - CURRENT_DATE))) AS f_allocated,
formatQty(qtyOrdered(sub.itemsite_id, (<? value("byDate") ?> - CURRENT_DATE))) AS f_ordered,
- formatQty(sub.itemsite_qtyonhand + qtyOrdered(sub.itemsite_id, (<? value("byDate") ?> - CURRENT_DATE)) - qtyAllocated(sub.itemsite_id, (<? value("byDate") ?> - CURRENT_DATE))) as f_avail
+ formatQty(qtyAvailable(sub.itemsite_id) + qtyOrdered(sub.itemsite_id, (<? value("byDate") ?> - CURRENT_DATE)) - qtyAllocated(sub.itemsite_id, (<? value("byDate") ?> - CURRENT_DATE))) as f_avail
<? 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
<? endif ?>
FROM item, itemsite AS sub, itemsite AS root, whsinfo, itemsub
WHERE ((sub.itemsite_item_id=item_id)
--- /dev/null
+SELECT setMetric('ServerVersion', '4.7.0Beta');
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);
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')
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;
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;
SELECT dropIfExists('view', 'saleshistory');
CREATE VIEW saleshistory AS
-SELECT cohist.*,
- CASE WHEN (cohist_invcnumber='-1') THEN 'Credit'
- ELSE cohist_invcnumber
- END AS invoicenumber,
- cust_id, cust_number, cust_name, cust_curr_id, cust_custtype_id, custtype_code, custtype_descrip,
- salesrep_number, salesrep_name, shipzone_id, shipzone_name, shipzone_descrip,
- itemsite_warehous_id, itemsite_item_id,
- item_id, item_number, item_descrip1, (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
- item_prodcat_id, warehous_code, warehous_descrip, prodcat_code,
- currtobase(cohist_curr_id, cohist_commission, cohist_invcdate) AS basecommission,
- currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate) AS baseunitprice,
- currtocurr(cohist_curr_id, cust_curr_id, cohist_unitprice, cohist_invcdate) AS custunitprice,
+SELECT *,
round((cohist_qtyshipped * cohist_unitprice), 2) AS extprice,
- round((cohist_qtyshipped * currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate)), 2) AS baseextprice,
- round((cohist_qtyshipped * currtocurr(cohist_curr_id, cust_curr_id, cohist_unitprice, cohist_invcdate)), 2) AS custextprice,
+ round((cohist_qtyshipped * baseunitprice), 2) AS baseextprice,
+ round((cohist_qtyshipped * custunitprice), 2) AS custextprice,
round((cohist_qtyshipped * cohist_unitcost), 4) AS extcost,
+ round((cohist_qtyshipped * baseunitprice) - (cohist_qtyshipped * cohist_unitcost), 2) AS margin,
+ CASE WHEN (cohist_qtyshipped * baseunitprice > 0.0) THEN
+ (round((cohist_qtyshipped * baseunitprice) - (cohist_qtyshipped * cohist_unitcost), 2) /
+ round((cohist_qtyshipped * baseunitprice), 2))
+ ELSE 0.0
+ END AS marginpercent,
currConcat(cohist_curr_id) AS currAbbr,
- 'Return'::TEXT AS cohist_invcdate_xtnullrole,
'qty'::TEXT AS cohist_qtyshipped_xtnumericrole,
'salesprice'::TEXT AS cohist_unitprice_xtnumericrole,
'salesprice'::TEXT AS baseunitprice_xtnumericrole,
'curr'::TEXT AS baseextprice_xtnumericrole,
'cost'::TEXT AS cohist_unitcost_xtnumericrole,
'curr'::TEXT AS extcost_xtnumericrole,
+ 'curr'::TEXT AS margin_xtnumericrole,
+ 'percent'::TEXT AS marginpercent_xtnumericrole,
'curr'::TEXT AS cohist_commission_xtnumericrole,
- 'curr'::TEXT AS basecommission_xtnumericrole,
- 0 AS cohist_qtyshipped_xttotalrole,
- 0 AS custextprice_xttotalrole,
- 0 AS baseextprice_xttotalrole,
- 0 AS extcost_xttotalrole,
- 0 AS basecommission_xttotalrole
+ 'curr'::TEXT AS basecommission_xtnumericrole
+FROM (
+SELECT cohist.*,
+ COALESCE(cohead_id,-1) AS cohead_id,
+ cust_id, cust_number, cust_name, cust_curr_id,
+ custtype_id, custtype_code, custtype_descrip,
+ salesrep_id, salesrep_number, salesrep_name,
+ shipzone_id, shipzone_name, shipzone_descrip,
+ saletype_code, saletype_descr,
+ itemsite_id,
+ warehous_id, warehous_code, warehous_descrip,
+ item_id, item_number, item_descrip1, item_descrip2,
+ (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
+ COALESCE(item_number, cohist_misc_descrip) AS itemnumber,
+ prodcat_id, prodcat_code,
+ currtobase(cohist_curr_id, cohist_commission, cohist_invcdate) AS basecommission,
+ currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate) AS baseunitprice,
+ currtocurr(cohist_curr_id, cust_curr_id, cohist_unitprice, cohist_invcdate) AS custunitprice
FROM cohist JOIN custinfo ON (cust_id=cohist_cust_id)
- JOIN custtype ON (custtype_id=cust_custtype_id)
- JOIN salesrep ON (salesrep_id=cohist_salesrep_id)
+ LEFT OUTER JOIN cohead ON (cohead_number=cohist_ordernumber)
+ LEFT OUTER JOIN custtype ON (custtype_id=cust_custtype_id)
+ LEFT OUTER JOIN salesrep ON (salesrep_id=cohist_salesrep_id)
+ LEFT OUTER JOIN shiptoinfo ON (shipto_id=cohist_shipto_id)
+ LEFT OUTER JOIN shipzone ON (shipzone_id=shipto_shipzone_id)
+ LEFT OUTER JOIN saletype ON (saletype_id=cohist_saletype_id)
JOIN itemsite ON (itemsite_id=cohist_itemsite_id)
JOIN site() ON (warehous_id=itemsite_warehous_id)
JOIN item ON (item_id=itemsite_item_id)
JOIN prodcat ON (prodcat_id=item_prodcat_id)
- LEFT OUTER JOIN shiptoinfo ON (shipto_id=cohist_shipto_id)
- LEFT OUTER JOIN shipzone ON (shipzone_id=shipto_shipzone_id);
+ ) AS data;
REVOKE ALL ON TABLE saleshistory FROM PUBLIC;
GRANT ALL ON TABLE saleshistory TO GROUP xtrole;
SELECT dropIfExists('view', 'saleshistorymisc');
CREATE VIEW saleshistorymisc AS
-SELECT cohist.*,
- CASE WHEN (cohist_invcnumber='-1') THEN 'Credit'
- ELSE cohist_invcnumber
- END AS invoicenumber,
- cust_id, cust_number, cust_name, cust_curr_id, cust_custtype_id, custtype_code,
- salesrep_number, salesrep_name, shipzone_id, shipzone_name,
- itemsite_warehous_id, itemsite_item_id,
- item_number, item_descrip1, (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
- item_prodcat_id, warehous_code, prodcat_code,
- currtobase(cohist_curr_id, cohist_commission, cohist_invcdate) AS basecommission,
- currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate) AS baseunitprice,
- currtocurr(cohist_curr_id, cust_curr_id, cohist_unitprice, cohist_invcdate) AS custunitprice,
+SELECT *,
round((cohist_qtyshipped * cohist_unitprice), 2) AS extprice,
- round((cohist_qtyshipped * currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate)), 2) AS baseextprice,
- round((cohist_qtyshipped * currtocurr(cohist_curr_id, cust_curr_id, cohist_unitprice, cohist_invcdate)), 2) AS custextprice,
+ round((cohist_qtyshipped * baseunitprice), 2) AS baseextprice,
+ round((cohist_qtyshipped * custunitprice), 2) AS custextprice,
round((cohist_qtyshipped * cohist_unitcost), 4) AS extcost,
+ round((cohist_qtyshipped * baseunitprice) - (cohist_qtyshipped * cohist_unitcost), 2) AS margin,
+ CASE WHEN (cohist_qtyshipped * baseunitprice > 0.0) THEN
+ (round((cohist_qtyshipped * baseunitprice) - (cohist_qtyshipped * cohist_unitcost), 2) /
+ round((cohist_qtyshipped * baseunitprice), 2))
+ ELSE 0.0
+ END AS marginpercent,
currConcat(cohist_curr_id) AS currAbbr,
- 'Return'::TEXT AS cohist_invcdate_xtnullrole,
'qty'::TEXT AS cohist_qtyshipped_xtnumericrole,
'salesprice'::TEXT AS cohist_unitprice_xtnumericrole,
'salesprice'::TEXT AS baseunitprice_xtnumericrole,
'curr'::TEXT AS baseextprice_xtnumericrole,
'cost'::TEXT AS cohist_unitcost_xtnumericrole,
'curr'::TEXT AS extcost_xtnumericrole,
+ 'curr'::TEXT AS margin_xtnumericrole,
+ 'percent'::TEXT AS marginpercent_xtnumericrole,
'curr'::TEXT AS cohist_commission_xtnumericrole,
- 'curr'::TEXT AS basecommission_xtnumericrole,
- 0 AS cohist_qtyshipped_xttotalrole,
- 0 AS custextprice_xttotalrole,
- 0 AS baseextprice_xttotalrole,
- 0 AS extcost_xttotalrole,
- 0 AS basecommission_xttotalrole
+ 'curr'::TEXT AS basecommission_xtnumericrole
+FROM (
+SELECT cohist.*,
+ COALESCE(cohead_id,-1) AS cohead_id,
+ cust_id, cust_number, cust_name, cust_curr_id,
+ custtype_id, custtype_code, custtype_descrip,
+ salesrep_id, salesrep_number, salesrep_name,
+ shipzone_id, shipzone_name, shipzone_descrip,
+ saletype_code, saletype_descr,
+ itemsite_id,
+ warehous_id, warehous_code, warehous_descrip,
+ item_id, item_number, item_descrip1, item_descrip2,
+ (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
+ COALESCE(item_number, cohist_misc_descrip) AS itemnumber,
+ prodcat_id, prodcat_code,
+ currtobase(cohist_curr_id, cohist_commission, cohist_invcdate) AS basecommission,
+ currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate) AS baseunitprice,
+ currtocurr(cohist_curr_id, cust_curr_id, cohist_unitprice, cohist_invcdate) AS custunitprice
FROM cohist JOIN custinfo ON (cust_id=cohist_cust_id)
- JOIN custtype ON (custtype_id=cust_custtype_id)
- JOIN salesrep ON (salesrep_id=cohist_salesrep_id)
+ LEFT OUTER JOIN cohead ON (cohead_number=cohist_ordernumber)
+ LEFT OUTER JOIN custtype ON (custtype_id=cust_custtype_id)
+ LEFT OUTER JOIN salesrep ON (salesrep_id=cohist_salesrep_id)
+ LEFT OUTER JOIN shiptoinfo ON (shipto_id=cohist_shipto_id)
+ LEFT OUTER JOIN shipzone ON (shipzone_id=shipto_shipzone_id)
+ LEFT OUTER JOIN saletype ON (saletype_id=cohist_saletype_id)
LEFT OUTER JOIN itemsite ON (itemsite_id=cohist_itemsite_id)
LEFT OUTER JOIN site() ON (warehous_id=itemsite_warehous_id)
LEFT OUTER JOIN item ON (item_id=itemsite_item_id)
LEFT OUTER JOIN prodcat ON (prodcat_id=item_prodcat_id)
- LEFT OUTER JOIN shiptoinfo ON (shipto_id=cohist_shipto_id)
- LEFT OUTER JOIN shipzone ON (shipzone_id=shipto_shipzone_id);
+WHERE (COALESCE(cohist_misc_type, '') <> 'F')
+ AND (COALESCE(cohist_misc_type, '') <> 'T')
+ ) AS data;
REVOKE ALL ON TABLE saleshistorymisc FROM PUBLIC;
GRANT ALL ON TABLE saleshistorymisc TO GROUP xtrole;
"characteristic.js",
"alarm.js",
"settings.js",
- "workflow.js"
+ "workflow.js",
+ "router.js"
);
--- /dev/null
+/*jshint indent:2, curly:true, eqeqeq:true, immed:true, latedef:true,
+newcap:true, noarg:true, regexp:true, undef:true, trailing:true,
+white:true*/
+/*global XT:true, XM:true, XV:true, Backbone:true, console:true */
+
+(function () {
+
+ XM.BackboneRouter = Backbone.Router.extend({
+
+ routes: {
+ "workspace/:recordType/:id": "workspace"
+ },
+
+ /**
+ @objectName {String} in format sales-order
+ */
+ workspace: function (objectName, id) {
+ var recordType = "XM." + objectName.charAt(0).toUpperCase() +
+ objectName.slice(1).camelize();
+ var inEvent = {
+ workspace: XV.getWorkspace(recordType),
+ id: id
+ };
+ XT.app.waterfallWorkspace(null, inEvent);
+ }
+
+ });
+ XM.backboneRouter = new XM.BackboneRouter();
+
+}());
+
/*jshint indent:2, curly:true, eqeqeq:true, immed:true, latedef:true,
newcap:true, noarg:true, regexp:true, undef:true, trailing:true,
white:true*/
-/*global enyo:true, XT:true, _:true, document:true, window:true, XM:true */
+/*global Backbone:true, enyo:true, XT:true, _:true, document:true, window:true, XM:true */
(function () {
if (!XT.baseCurrency()) {
this.waterfallNoBaseCurr();
}
+ Backbone.history.start();
}
},
start: function (debug) {
/**
Add component or array of component view(s) to a view class that
- has implemented the `extensionsMixin`.
+ has implemented the `ExtensionsMixin`.
Examples of classes that support extensions are:
* `Workspace`
+ * `List`
* `ParameterWidget`
@param {String} Class name
@defaultPanelWidth: 320px;
@toolbarHeight: 55px;
@searchLength: 185px;
+// popups
+@maxMessageHeight: 500px;
+@maxMessageWidth: 500px;
// libs
@import "../../lib/font-awesome/less/font-awesome.less";
*/
.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;
*/
.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;
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
*/
this._setProperty("value", value, "valueChanged");
collection = value;
+ if (this.getEditableIndex() !== null) {
+ // do not try to sort while the user is entering data
+ return;
+ }
+
if (orderBy && !collection.comparator) {
collection.comparator = function (a, b) {
var aval,
Note: enyo.List includes a scroller; therefore, XV.List should not be placed inside a scroller.
@extends XV.ListBase
*/
- enyo.kind(/** @lends XV.List# */{
+ enyo.kind(_.extend(/** @lends XV.List# */{
name: "XV.List",
kind: "XV.ListBase",
classes: "xv-list",
*/
create: function () {
this.inherited(arguments);
+ this.processExtensions();
var actions = this.getActions() || [],
deleteAction = _.findWhere(actions, {"name": "delete"}),
privilege,
}
}
}
- });
+ }, XV.ExtensionsMixin));
}());
{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},
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 () {
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;
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());
// 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
// 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);
}
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) {
} 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
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
}
this._activeNotify = activeIndex;
- notifyButtons[activeIndex].addClass("onyx-blue");
+ notifyButtons[activeIndex].addClass("selected");
}
},
/**
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,
} else {
attrs[Klass.prototype.idAttribute] = recordId;
this.setValue(Klass.findOrCreate(attrs));
+ XM.backboneRouter.navigate("workspace/" +
+ this.value.recordType.substring(3).decamelize().replace(/_/g, "-") +
+ "/" + recordId);
}
_setBindings(this, "on");
this.fetch();
model.revert();
}
+ XM.backboneRouter.navigate("");
if (model && model.hasLockKey && model.hasLockKey()) {
model.releaseLock({
success: function () {
attr: null,
scale: 0,
formatting: true,
- type: "number",
label: "",
showLabel: true
},
-do $$
- /* Only create the schema if it hasn't been created already */
- var res, sql = "select schema_name from information_schema.schemata where schema_name = 'sys'",
- res = plv8.execute(sql);
- if (!res.length) {
- sql = "create schema sys; grant all on schema sys to group xtrole;"
- plv8.execute(sql);
- }
-$$ language plv8;
+select xt.create_schema('sys');
-do $$
- /* Only create the schema if it hasn't been created already */
- var res, sql = "select schema_name from information_schema.schemata where schema_name = 'xm'",
- res = plv8.execute(sql);
- if (!res.length) {
- sql = "create schema xm; grant all on schema xm to group xtrole;"
- plv8.execute(sql);
- }
-$$ language plv8;
\ No newline at end of file
+select xt.create_schema('xm');
"version": "1.3.9",
"databaseScripts": [
"create_plv8.sql",
- "create_xm_schema.sql",
+ "xt/functions/create_schema.sql",
"create_sys_schema.sql",
+ "create_xm_schema.sql",
"xt/functions/add_inheritance.sql",
"xt/functions/any_numeric.sql",
"xt/functions/any_text.sql",
--- /dev/null
+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';
+
+
--- /dev/null
+create or replace function xt.create_schema(sch text) returns boolean volatile as $$
+declare
+ count integer;
+ query text;
+begin
+
+ /* Only create the schema if it hasn't been created already */
+ perform *
+ from information_schema.schemata
+ where schema_name = sch;
+
+ get diagnostics count = row_count;
+
+ if (count > 0) then
+ return false;
+ end if;
+
+ query = 'create schema ' || sch || ';' ||
+ 'grant all on schema ' || sch || ' to group xtrole;';
+ execute query;
+
+ return true;
+
+end;
+$$ language 'plpgsql';
var extensionLocation = extension.location === "npm" ? extension.location : extension.location + "/source";
useClientDir(extensionLocation + "/" + extension.name + "/client", X.path.join(getExtensionDir(extension), "client"));
};
- var loadExtensionRoutes = function (extension) {
- var manifest = JSON.parse(X.fs.readFileSync(X.path.join(getExtensionDir(extension),
- "database/source/manifest.js")));
+ var loadExtensionServerside = function (extension) {
+ var packagePath = X.path.join(getExtensionDir(extension), "package.json");
+ var packageJson = X.fs.existsSync(packagePath) ? require(packagePath) : undefined;
+ var manifestPath = X.path.join(getExtensionDir(extension), "database/source/manifest.js");
+ var manifest = X.fs.existsSync(manifestPath) ? JSON.parse(X.fs.readFileSync(manifestPath)) : {};
+ var version = packageJson ? packageJson.version : manifest.version;
+ X.versions[extension.name] = version || "none"; // XXX the "none" is temporary until we have core extensions in npm
+
+ // TODO: be able to define routes in package.json
_.each(manifest.routes || [], function (routeDetails) {
var verb = (routeDetails.verb || "all").toLowerCase(),
func = require(X.path.join(getExtensionDir(extension),
return;
}
useClientDir("/client", "../enyo-client/application");
- _.each(results, loadExtensionRoutes);
+ _.each(results, loadExtensionServerside);
_.each(results, loadExtensionClientside);
}
});
*/
var packageJson = X.fs.readFileSync("../package.json");
-try {
- X.version = JSON.parse(packageJson).version;
-} catch (error) {
-
-}
+X.versions = {
+ core: JSON.parse(packageJson).version
+};
/**
* Module dependencies.
req.path === "/" ||
req.path === "/favicon.ico" ||
req.path === "/forgot-password" ||
+ req.path === '/node_modules/jquery/jquery.js' ||
req.path === "/recover") {
next();
app.use(express.favicon(__dirname + '/views/login/assets/favicon.ico'));
app.use('/assets', express.static('views/login/assets', { maxAge: 86400000 }));
+app.use('/node_modules/jquery', express.static('../node_modules/jquery/dist', { maxAge: 86400000 }));
app.get('/:org/dialog/authorize', oauth2.authorization);
app.post('/:org/dialog/authorize/decision', oauth2.decision);
data: session.passport.user,
code: 1,
debugging: X.options.datasource.debugging,
- biAvailable: _.isObject(X.options.biServer) && !_.isEmpty(X.options.biServer),
emailAvailable: _.isString(X.options.datasource.smtpHost) && X.options.datasource.smtpHost !== "",
printAvailable: _.isString(X.options.datasource.printer) && X.options.datasource.printer !== "",
- version: X.version
+ versions: X.versions
});
callback(callbackObj);
}, data && data.payload);
//passport.authenticate('local', { successReturnToOrRedirect: '/login/scope', failureRedirect: '/', failureFlash: 'Invalid username or password.' }),
passport.authenticate('local', { failureRedirect: '/?login=fail' }),
function (req, res, next) {
-
+ var pathName = "/app";
if (req && req.session && !req.session.oauth2 && req.session.passport && req.session.passport.user && req.session.passport.user.organization) {
- res.redirect("/" + req.session.passport.user.organization + '/app');
+ if (req.body.hash && req.body.hash.charAt(0) === "#") {
+ pathName = pathName + req.body.hash;
+ }
+ res.redirect("/" + req.session.passport.user.organization + pathName);
//next();
} else {
exports.scopeForm(req, res, next);
(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"),
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;
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
<!-- js -->
<script src="/<%= org %>/locale"></script>
<script src="/socket.io/socket.io.js?1.3.10" type="text/javascript"></script>
+ <script src="/node_modules/jquery/jquery.js"></script>
<script src="/<%= org %>/client/build/client-code?uuid=<%= coreJs %>&language=js"></script>
<% for (var i = 0; i < extensionJsArray.length; i++) { %>
<script src="/<%= org %>/client/build/client-code?uuid=<%= extensionJsArray[i] %>&language=js"></script>
</script>
<script src="/<%= org %>/client/lib/module/less/dist/less-1.5.0.js"></script>
<script src="/<%= org %>/client/enyo/enyo.js"></script>
+ <script src="/node_modules/jquery/jquery.js"></script>
<!-- application (debug) -->
<link href="/<%= org %>/client/lib/enyo-x/lib/nvd3/src/nv.d3.css" rel="stylesheet"/>
<script src="/<%= org %>/locale?debug=true"></script>
<section id="main">
<div style="transform: translateZ(0px); opacity: 1;" id="form-fields">
<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++) { %>
<% } %>
</section>
- <!-- <div class="footer">
- <div class="footer-container">
- <p>
- Visit the <a href='http://www.xtuple.org/docs/mobile-web-demo-guide'>Mobile Web Demo Guide</a>,
- or send email to <a href='mailto:demo@xtuple.com'>demo@xtuple.com</a> for help.
- </p>
-
- <p>
- This MOBILE WEB CLIENT provides access the CRM, Project and Sales modules of xTuple.
- You must use the DESKTOP CLIENT to access the full application, including CRM, Projects, Sales, Purchasing, Inventory, Manufacturing, Scheduling and Accounting modules.
- </p>
-
- <p>
- Download the xTuple Desktop client here: <a href=''>Windows</a>,
- <a href=''>Mac</a>, <a href=''>Linux</a>
- </p>
-
- <p>v1.4.5</p>
- </div>
- </div> -->
-
<script>
document.loginForm.id.focus();
+ document.loginForm.hash.value = window.location.hash;
</script>
</body>
</html>
display: block;
width: 97%;
margin: 0;
- text-transform: lowercase;
outline: none;
color: #666666;
font-smoothing: antialiased;
// 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));
- });
});
}());
{
"name": "xtuple",
- "version": "4.4.1",
+ "version": "4.7.0-beta",
"dependencies": {
"async": {
"version": "0.2.10",
- "from": "async@0.2.x"
+ "from": "async@0.2.x",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
},
"backbone": {
"version": "0.9.10",
},
"backbone-relational": {
"version": "0.8.0",
- "from": "backbone-relational@0.8.0",
- "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": "bcrypt@0.7.x",
- "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-0.7.8.tgz",
"dependencies": {
"bindings": {
"version": "1.0.0",
- "from": "bindings@1.0.0",
- "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.x"
"commander": {
"version": "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",
"version": "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.x"
"express": {
"version": "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",
},
"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",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.0.tgz"
},
"debug": {
- "version": "0.8.1",
+ "version": "1.0.4",
"from": "debug@*",
- "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz"
+ "dependencies": {
+ "ms": {
+ "version": "0.6.2",
+ "from": "ms@0.6.2"
+ }
+ }
}
}
},
}
}
},
- "ipp": {
- "version": "0.0.5",
- "from": "ipp@0.0.5",
- "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",
- "resolved": "git://github.com/xtuple/JSON-Patch.git#eb69a78f6d041b2f630a9747a5b227c42c8df077"
- },
- "less": {
- "version": "1.5.0",
- "from": "less@1.5.0",
- "resolved": "https://registry.npmjs.org/less/-/less-1.5.0.tgz",
+ "googleapis": {
+ "version": "0.4.7",
+ "from": "googleapis@~0.4.6",
+ "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-0.4.7.tgz",
"dependencies": {
- "mime": {
- "version": "1.2.11",
- "from": "mime@1.2.x",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
- },
- "mkdirp": {
- "version": "0.3.5",
- "from": "mkdirp@~0.3.4"
- },
- "clean-css": {
- "version": "1.0.12",
- "from": "clean-css@1.0.x",
+ "request": {
+ "version": "2.25.0",
+ "from": "request@~2.25.0",
"dependencies": {
- "commander": {
- "version": "1.3.2",
- "from": "commander@1.3.x",
+ "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.2",
+ "from": "forever-agent@~0.5.0"
+ },
+ "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": {
- "keypress": {
- "version": "0.1.0",
- "from": "keypress@0.1.x"
+ "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"
}
}
- }
- }
- },
- "source-map": {
- "version": "0.1.33",
- "from": "source-map@0.1.x",
- "dependencies": {
- "amdefine": {
- "version": "0.1.0",
- "from": "amdefine@>=0.0.4"
- }
- }
- }
- }
- },
- "moment": {
- "version": "2.4.0",
- "from": "moment@2.4.x"
- },
- "nodemailer": {
- "version": "0.3.44",
- "from": "nodemailer@0.3.x",
- "dependencies": {
- "mailcomposer": {
- "version": "0.2.9",
- "from": "mailcomposer@>= 0.1.29",
- "dependencies": {
- "mimelib": {
- "version": "0.2.14",
- "from": "mimelib@~0.2.14",
+ },
+ "hawk": {
+ "version": "1.0.0",
+ "from": "hawk@~1.0.0",
"dependencies": {
- "encoding": {
- "version": "0.1.7",
- "from": "encoding@~0.1",
- "dependencies": {
- "iconv-lite": {
- "version": "0.2.11",
- "from": "iconv-lite@~0.2.11"
- }
- }
+ "hoek": {
+ "version": "0.9.1",
+ "from": "hoek@0.9.x"
},
- "addressparser": {
- "version": "0.2.1",
- "from": "addressparser@~0.2.0"
+ "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"
}
}
},
- "mime": {
- "version": "1.2.11",
- "from": "mime@~1.2.9",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
- },
- "he": {
- "version": "0.3.6",
- "from": "he@~0.3.6"
+ "aws-sign": {
+ "version": "0.3.0",
+ "from": "aws-sign@~0.3.0"
},
- "punycode": {
- "version": "1.2.4",
- "from": "punycode@~1.2.3"
+ "oauth-sign": {
+ "version": "0.3.0",
+ "from": "oauth-sign@~0.3.0"
},
- "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"
+ "cookie-jar": {
+ "version": "0.3.0",
+ "from": "cookie-jar@~0.3.0"
},
- "dkim-signer": {
- "version": "0.1.0",
- "from": "dkim-signer@~0.1.0"
- }
- }
- },
- "simplesmtp": {
- "version": "0.3.29",
- "from": "simplesmtp@>= 0.1.28",
- "resolved": "https://registry.npmjs.org/simplesmtp/-/simplesmtp-0.3.29.tgz",
- "dependencies": {
- "rai": {
- "version": "0.1.10",
- "from": "rai@~0.1.10",
- "resolved": "https://registry.npmjs.org/rai/-/rai-0.1.10.tgz"
+ "node-uuid": {
+ "version": "1.4.1",
+ "from": "node-uuid@~1.4.0"
},
- "xoauth2": {
- "version": "0.1.8",
- "from": "xoauth2@~0.1"
- }
- }
- },
- "optimist": {
- "version": "0.6.1",
- "from": "optimist@*",
- "dependencies": {
- "wordwrap": {
- "version": "0.0.2",
- "from": "wordwrap@~0.0.2"
+ "mime": {
+ "version": "1.2.11",
+ "from": "mime@~1.2.9"
},
- "minimist": {
- "version": "0.0.9",
- "from": "minimist@~0.0.1",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.9.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"
+ }
+ }
+ },
+ "async": {
+ "version": "0.9.0",
+ "from": "async@~0.9.0"
+ }
+ }
}
}
- }
- }
- },
- "node-forge": {
- "version": "0.6.2",
- "from": "node-forge@0.6.x"
- },
- "npm": {
- "version": "1.4.16",
- "from": "npm@1.4.x",
- "resolved": "https://registry.npmjs.org/npm/-/npm-1.4.16.tgz",
- "dependencies": {
- "abbrev": {
- "version": "1.0.5",
- "from": "abbrev@latest",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz"
- },
- "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": "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"
+ "async": {
+ "version": "0.2.6",
+ "from": "async@0.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.6.tgz"
},
- "chmodr": {
+ "gapitoken": {
"version": "0.1.0",
- "from": "chmodr@latest"
- },
- "chownr": {
- "version": "0.0.1",
- "from": "../chownr"
- },
- "cmd-shim": {
- "version": "1.1.1",
- "from": "cmd-shim@latest",
- "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-1.1.1.tgz"
- },
- "columnify": {
- "version": "1.1.0",
- "from": "columnify@latest",
- "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.1.0.tgz",
- "dependencies": {
- "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": {
- "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"
- }
- }
- },
- "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"
- }
- }
- }
- }
- },
- "editor": {
- "version": "0.1.0",
- "from": "editor@latest",
- "resolved": "https://registry.npmjs.org/editor/-/editor-0.1.0.tgz"
- },
- "fstream": {
- "version": "0.1.27",
- "from": "fstream@~0.1.26"
- },
- "fstream-npm": {
- "version": "0.1.7",
- "from": "fstream-npm@latest",
- "dependencies": {
- "fstream-ignore": {
- "version": "0.0.8",
- "from": "fstream-ignore@~0.0",
- "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-0.0.8.tgz"
- }
- }
- },
- "github-url-from-git": {
- "version": "1.1.1",
- "from": "github-url-from-git@1.1.1",
- "resolved": "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.1.1.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.2",
- "from": "glob@latest",
- "resolved": "https://registry.npmjs.org/glob/-/glob-4.0.2.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": "0.1.0",
- "from": "init-package-json@latest",
- "dependencies": {
- "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": "0.3.0",
- "from": "minimatch@latest",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.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.3.5",
- "from": "mkdirp@latest"
- },
- "node-gyp": {
- "version": "0.13.1",
- "from": "node-gyp@~0.13.0",
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-0.13.1.tgz"
- },
- "nopt": {
- "version": "3.0.0",
- "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.2",
- "from": "npm-registry-client@latest"
- },
- "npm-user-validate": {
- "version": "0.1.0",
- "from": "npm-user-validate@latest"
- },
- "npmconf": {
- "version": "1.0.5",
- "from": "npmconf@latest",
+ "from": "gapitoken@0.1.0",
+ "resolved": "https://registry.npmjs.org/gapitoken/-/gapitoken-0.1.0.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",
+ "jws": {
+ "version": "0.0.2",
+ "from": "jws@0.0.2",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-0.0.2.tgz",
"dependencies": {
- "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"
+ "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"
}
}
}
}
- },
- "npmlog": {
- "version": "0.1.1",
- "from": "npmlog@latest"
- },
- "once": {
- "version": "1.3.0",
- "from": "once@latest"
- },
- "opener": {
- "version": "1.3.0",
- "from": "opener@latest"
- },
- "osenv": {
- "version": "0.1.0",
- "from": "osenv@~0.1.0"
- },
- "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"
- },
- "read": {
- "version": "1.0.5",
- "from": "read@latest",
- "dependencies": {
- "mute-stream": {
- "version": "0.0.4",
- "from": "mute-stream@~0.0.4"
- }
- }
- },
- "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.2",
- "from": "read-package-json@latest",
- "dependencies": {
- "normalize-package-data": {
- "version": "0.3.0",
- "from": "normalize-package-data@^0.3.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-0.3.0.tgz"
- }
- }
- },
- "request": {
- "version": "2.30.0",
- "from": "request@latest",
+ }
+ }
+ },
+ "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": {
- "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.1.2",
- "from": "form-data@~0.1.0",
+ "htmlparser2": {
+ "version": "3.7.3",
+ "from": "htmlparser2@>= 3.1.5 <4",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.7.3.tgz",
"dependencies": {
- "combined-stream": {
- "version": "0.0.4",
- "from": "combined-stream@~0.0.4",
+ "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",
+ "from": "readable-stream@1.1",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz",
"dependencies": {
- "delayed-stream": {
- "version": "0.0.5",
- "from": "delayed-stream@0.0.5"
+ "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"
}
}
},
- "async": {
- "version": "0.2.9",
- "from": "async@~0.2.9"
+ "entities": {
+ "version": "1.0.0",
+ "from": "entities@1.0"
}
}
},
- "tunnel-agent": {
+ "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": "tunnel-agent@~0.3.0"
+ "from": "cssom@~0.3.0"
},
- "http-signature": {
- "version": "0.10.0",
- "from": "http-signature@~0.10.0",
+ "cssstyle": {
+ "version": "0.2.14",
+ "from": "cssstyle@~0.2.9"
+ },
+ "contextify": {
+ "version": "0.1.8",
+ "from": "contextify@~0.1.5",
"dependencies": {
- "assert-plus": {
- "version": "0.1.2",
- "from": "assert-plus@0.1.2"
- },
- "asn1": {
- "version": "0.1.11",
- "from": "asn1@0.1.11"
+ "bindings": {
+ "version": "1.2.1",
+ "from": "bindings@*",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
},
- "ctype": {
- "version": "0.5.2",
- "from": "ctype@0.5.2"
+ "nan": {
+ "version": "1.0.0",
+ "from": "nan@~1.0.0"
}
}
- },
- "oauth-sign": {
- "version": "0.3.0",
- "from": "oauth-sign@~0.3.0"
- },
- "hawk": {
- "version": "1.0.0",
- "from": "hawk@~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",
+ "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"
+ },
+ "cli": {
+ "version": "0.4.5",
+ "from": "cli@0.4.x",
+ "dependencies": {
+ "glob": {
+ "version": "4.0.5",
+ "from": "glob@>= 3.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-4.0.5.tgz",
"dependencies": {
- "hoek": {
- "version": "0.9.1",
- "from": "hoek@0.9.x"
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@2"
},
- "boom": {
- "version": "0.4.2",
- "from": "boom@0.4.x"
+ "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"
+ }
+ }
},
- "cryptiles": {
- "version": "0.2.2",
- "from": "cryptiles@0.2.x"
+ "once": {
+ "version": "1.3.0",
+ "from": "once@^1.3.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.0.tgz"
},
- "sntp": {
- "version": "0.2.4",
- "from": "sntp@0.2.x"
+ "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"
}
}
- },
- "aws-sign2": {
- "version": "0.5.0",
- "from": "aws-sign2@~0.5.0"
}
}
},
- "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"
+ "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"
+ }
+ }
},
- "sha": {
- "version": "1.2.4",
- "from": "sha@latest",
- "resolved": "https://registry.npmjs.org/sha/-/sha-1.2.4.tgz",
+ "htmlparser2": {
+ "version": "3.3.0",
+ "from": "htmlparser2@3.3.x",
"dependencies": {
+ "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.27-1",
+ "version": "1.0.31",
"from": "readable-stream@1.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.31.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"
+ "from": "core-util-is@~1.0.0"
},
"isarray": {
"version": "0.0.1",
- "from": "isarray@0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ "from": "isarray@0.0.1"
},
"string_decoder": {
- "version": "0.10.25-1",
+ "version": "0.10.31",
"from": "string_decoder@~0.10.x",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz"
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "from": "inherits@~2.0.1"
}
}
}
}
},
- "slide": {
- "version": "1.1.5",
- "from": "slide@latest"
- },
- "sorted-object": {
- "version": "1.0.0",
- "from": "sorted-object@"
- },
- "tar": {
- "version": "0.1.19",
- "from": "tar@0.1.19",
- "resolved": "https://registry.npmjs.org/tar/-/tar-0.1.19.tgz"
- },
- "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"
+ "console-browserify": {
+ "version": "0.1.6",
+ "from": "console-browserify@0.1.x"
},
- "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"
+ "exit": {
+ "version": "0.1.2",
+ "from": "exit@0.1.x"
}
}
},
- "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"
- }
- }
+ "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.x",
+ "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.x"
+ "mime": {
+ "version": "1.2.11",
+ "from": "mime@~1.2.7"
+ },
+ "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"
+ }
+ }
+ }
+ }
},
- "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"
+ "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.x",
+ "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.x"
+ "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.x",
- "dependencies": {
- "pkginfo": {
- "version": "0.2.3",
- "from": "pkginfo@0.2.x"
- }
- }
+ "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.x",
- "dependencies": {
- "pkginfo": {
- "version": "0.2.3",
- "from": "pkginfo@0.2.x"
- }
- }
+ "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.x",
+ "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.x"
+ "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": "paynode@0.3.6",
- "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@*",
+ "update-notifier": {
+ "version": "0.1.10",
+ "from": "update-notifier@~0.1.8",
"dependencies": {
- "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"
+ "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"
+ }
+ }
},
- "semver": {
- "version": "2.2.1",
- "from": "semver@=2.2.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-2.2.1.tgz"
+ "configstore": {
+ "version": "0.3.1",
+ "from": "configstore@^0.3.0",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.1.tgz",
+ "dependencies": {
+ "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"
+ },
+ "osenv": {
+ "version": "0.1.0",
+ "from": "osenv@~0.1.0",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.0.tgz"
+ },
+ "uuid": {
+ "version": "1.4.1",
+ "from": "uuid@~1.4.1"
+ }
+ }
},
- "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",
+ "request": {
+ "version": "2.40.0",
+ "from": "request@^2.36.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.40.0.tgz",
"dependencies": {
- "core-util-is": {
- "version": "1.0.1",
- "from": "core-util-is@~1.0.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"
+ }
+ }
},
- "string_decoder": {
- "version": "0.10.25-1",
- "from": "string_decoder@~0.10.x"
+ "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"
},
- "debuglog": {
- "version": "0.0.2",
- "from": "debuglog@0.0.2",
- "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.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"
}
}
},
- "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",
- "dependencies": {
- "sax": {
- "version": "0.6.0",
- "from": "sax@>=0.1.1"
- }
- }
+ "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"
},
- "source-map-support": {
- "version": "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",
+ "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": "source-map@0.1.8",
- "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.0.4"
+ "wordwrap": {
+ "version": "0.0.2",
+ "from": "wordwrap@>=0.0.1 <0.1.0"
}
}
}
}
}
},
- "pg": {
- "version": "0.14.1",
- "from": "pg@0.14.x",
+ "npm": {
+ "version": "1.4.24",
+ "from": "npm@1.4.x",
"dependencies": {
- "generic-pool": {
- "version": "2.0.4",
- "from": "generic-pool@~2.0.2"
+ "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.x",
- "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": {
+ "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": {
+ "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"
+ }
+ }
+ },
+ "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"
+ }
+ }
+ }
+ }
+ },
+ "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": {
+ "fstream-ignore": {
+ "version": "1.0.1",
+ "from": "fstream-ignore@^1.0.0"
+ }
+ }
+ },
+ "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": {
+ "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": {
- "combined-stream": {
- "version": "0.0.4",
- "from": "combined-stream@~0.0.4",
- "dependencies": {
- "delayed-stream": {
- "version": "0.0.5",
- "from": "delayed-stream@0.0.5"
- }
- }
- },
- "async": {
- "version": "0.1.22",
- "from": "async@~0.1.9"
+ "sigmund": {
+ "version": "1.0.0",
+ "from": "sigmund@~1.0.0",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz"
}
}
},
- "mime": {
- "version": "1.2.9",
- "from": "mime@~1.2.7"
- }
- }
- },
- "rimraf": {
- "version": "2.2.8",
- "from": "rimraf@2.2.x",
- "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",
+ "mkdirp": {
+ "version": "0.5.0",
+ "from": "mkdirp@latest",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
"dependencies": {
- "keypress": {
- "version": "0.1.0",
- "from": "keypress@0.1.x"
+ "minimist": {
+ "version": "0.0.8",
+ "from": "minimist@0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
}
}
- }
- }
- },
- "socket.io": {
- "version": "0.9.16",
- "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",
+ },
+ "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": {
- "uglify-js": {
- "version": "1.2.5",
- "from": "uglify-js@1.2.5"
- },
- "ws": {
- "version": "0.4.31",
- "from": "ws@0.4.x",
- "dependencies": {
- "commander": {
- "version": "0.6.1",
- "from": "commander@~0.6.1"
- },
- "nan": {
- "version": "0.3.2",
- "from": "nan@~0.3.0"
- },
- "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"
- },
- "active-x-obfuscator": {
- "version": "0.0.1",
- "from": "active-x-obfuscator@0.0.1",
+ "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": "policyfile@0.0.4",
- "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": "redis@0.7.3",
- "resolved": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz"
- }
- }
- },
- "underscore": {
- "version": "1.4.4",
- "from": "underscore@1.4.x"
- },
- "winston": {
- "version": "0.7.3",
- "from": "winston@0.7.x",
- "dependencies": {
- "cycle": {
- "version": "1.0.3",
- "from": "cycle@1.0.x"
+ "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.x"
+ "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.x"
+ "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"
+ }
+ }
},
- "request": {
- "version": "2.16.6",
- "from": "request@2.16.x",
+ "read-package-json": {
+ "version": "1.2.6",
+ "from": "read-package-json@latest",
"dependencies": {
- "form-data": {
- "version": "0.0.10",
- "from": "form-data@~0.0.3",
- "dependencies": {
- "combined-stream": {
- "version": "0.0.4",
- "from": "combined-stream@~0.0.4",
- "dependencies": {
- "delayed-stream": {
- "version": "0.0.5",
- "from": "delayed-stream@0.0.5"
- }
- }
- }
- }
- },
- "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"
- },
- "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"
+ "normalize-package-data": {
+ "version": "1.0.0",
+ "from": "normalize-package-data@^1.0.0"
}
}
},
- "stack-trace": {
- "version": "0.0.9",
- "from": "stack-trace@0.0.x"
- }
- }
- },
- "xmla4js": {
- "version": "0.0.2",
- "from": "xmla4js@git://github.com/rpbouman/xmla4js.git",
- "resolved": "git://github.com/rpbouman/xmla4js.git#40a0be2637c3f18c986d3e5cbe4c32cf8f995531"
- },
- "underscore.string": {
- "version": "2.3.3",
- "from": "underscore.string@~2.3.3"
- },
- "ursa": {
- "version": "0.8.0",
- "from": "ursa@0.8.x"
- },
- "xtuple-query": {
- "version": "1.0.0",
- "from": "xtuple-query@~1.0.0",
- "dependencies": {
- "congruence": {
- "version": "1.2.3",
- "from": "congruence@1.2.3",
- "resolved": "https://registry.npmjs.org/congruence/-/congruence-1.2.3.tgz"
- },
- "underscore": {
- "version": "1.5.2",
- "from": "underscore@~1.5.2"
- }
- }
- },
- "googleapis": {
- "version": "0.4.7",
- "from": "googleapis@~0.4.6",
- "dependencies": {
"request": {
- "version": "2.25.0",
- "from": "request@~2.25.0",
+ "version": "2.30.0",
+ "from": "request@latest",
"dependencies": {
"qs": {
"version": "0.6.6",
"from": "json-stringify-safe@~5.0.0"
},
"forever-agent": {
- "version": "0.5.2",
+ "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.1.2",
+ "from": "form-data@~0.1.0",
+ "dependencies": {
+ "combined-stream": {
+ "version": "0.0.4",
+ "from": "combined-stream@~0.0.4",
+ "dependencies": {
+ "delayed-stream": {
+ "version": "0.0.5",
+ "from": "delayed-stream@0.0.5"
+ }
+ }
+ },
+ "async": {
+ "version": "0.2.9",
+ "from": "async@~0.2.9"
+ }
+ }
+ },
"tunnel-agent": {
"version": "0.3.0",
"from": "tunnel-agent@~0.3.0"
}
}
},
+ "oauth-sign": {
+ "version": "0.3.0",
+ "from": "oauth-sign@~0.3.0"
+ },
"hawk": {
"version": "1.0.0",
"from": "hawk@~1.0.0",
}
}
},
- "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.0"
- },
- "mime": {
- "version": "1.2.11",
- "from": "mime@~1.2.9",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
- },
- "form-data": {
- "version": "0.1.2",
- "from": "form-data@~0.1.0",
- "dependencies": {
- "combined-stream": {
- "version": "0.0.4",
- "from": "combined-stream@~0.0.4",
- "dependencies": {
- "delayed-stream": {
- "version": "0.0.5",
- "from": "delayed-stream@0.0.5"
- }
- }
- },
- "async": {
- "version": "0.2.10",
- "from": "async@~0.2.9"
- }
- }
+ "aws-sign2": {
+ "version": "0.5.0",
+ "from": "aws-sign2@~0.5.0"
}
}
},
- "async": {
- "version": "0.2.6",
- "from": "async@0.2.6",
- "resolved": "https://registry.npmjs.org/async/-/async-0.2.6.tgz"
+ "retry": {
+ "version": "0.6.0",
+ "from": "retry"
},
- "gapitoken": {
- "version": "0.1.0",
- "from": "gapitoken@0.1.0",
- "resolved": "https://registry.npmjs.org/gapitoken/-/gapitoken-0.1.0.tgz",
+ "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": {
- "jws": {
- "version": "0.0.2",
- "from": "jws@0.0.2",
+ "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": {
- "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"
- }
- }
- }
- }
- }
- }
- },
- "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.2",
- "from": "deep-is@0.1.x"
- }
- }
- },
- "deep-equal": {
- "version": "0.0.0",
- "from": "deep-equal@~0.0.0"
- },
- "buffer-equal": {
- "version": "0.0.0",
- "from": "buffer-equal@~0.0.0"
- }
- }
+ "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"
},
- "base64url": {
- "version": "0.0.3",
- "from": "base64url@0.0.3",
- "resolved": "https://registry.npmjs.org/base64url/-/base64url-0.0.3.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@"
}
}
},
- "chai": {
- "version": "1.5.0",
- "from": "chai@1.5.x"
- },
- "require-uncache": {
- "version": "0.0.2",
- "from": "require-uncache@0.0.x"
+ "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"
+ }
+ }
},
- "csslint": {
- "version": "0.10.0",
- "from": "csslint@~0.10.0",
+ "oauth2orize-jwt-bearer": {
+ "version": "0.1.0",
+ "from": "oauth2orize-jwt-bearer@0.1.x",
"dependencies": {
- "parserlib": {
- "version": "0.2.5",
- "from": "parserlib@~0.2.2",
- "resolved": "https://registry.npmjs.org/parserlib/-/parserlib-0.2.5.tgz"
+ "pkginfo": {
+ "version": "0.2.3",
+ "from": "pkginfo@0.2.x"
}
}
},
- "mocha": {
- "version": "1.9.0",
- "from": "mocha@1.9.x",
+ "passport": {
+ "version": "0.1.18",
+ "from": "passport@0.1.x",
"dependencies": {
- "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",
- "dependencies": {
- "mkdirp": {
- "version": "0.3.0",
- "from": "mkdirp@0.3.0",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz"
- }
- }
- },
- "diff": {
- "version": "1.0.2",
- "from": "diff@1.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.2.tgz"
- },
- "debug": {
- "version": "0.8.1",
- "from": "debug@*",
- "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz"
- },
- "mkdirp": {
- "version": "0.3.3",
- "from": "mkdirp@0.3.3",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.3.tgz"
+ "pkginfo": {
+ "version": "0.2.3",
+ "from": "pkginfo@0.2.x"
},
- "ms": {
- "version": "0.3.0",
- "from": "ms@0.3.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.3.0.tgz"
+ "pause": {
+ "version": "0.0.1",
+ "from": "pause@0.0.1"
}
}
},
- "zombie": {
- "version": "1.4.1",
- "from": "zombie@1.4.x",
+ "passport-http": {
+ "version": "0.2.2",
+ "from": "passport-http@0.2.x",
"dependencies": {
- "eventsource": {
- "version": "0.0.10",
- "from": "eventsource@~0.0.5"
- },
- "jsdom": {
- "version": "0.2.19",
- "from": "jsdom@~0.2.15",
+ "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"
+ }
+ }
+ },
+ "passport-oauth2-jwt-bearer": {
+ "version": "0.1.1",
+ "from": "passport-oauth2-jwt-bearer@0.1.x",
+ "dependencies": {
+ "pkginfo": {
+ "version": "0.2.3",
+ "from": "pkginfo@0.2.x"
+ }
+ }
+ },
+ "paynode": {
+ "version": "0.3.6",
+ "from": "paynode@0.3.6",
+ "dependencies": {
+ "braintree": {
+ "version": "1.17.0",
+ "from": "braintree@*",
+ "resolved": "https://registry.npmjs.org/braintree/-/braintree-1.17.0.tgz",
"dependencies": {
- "htmlparser": {
- "version": "1.7.7",
- "from": "htmlparser@1.x"
+ "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"
},
- "cssom": {
- "version": "0.2.5",
- "from": "cssom@0.2.x"
+ "semver": {
+ "version": "2.2.1",
+ "from": "semver@=2.2.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-2.2.1.tgz"
},
- "cssstyle": {
- "version": "0.2.11",
- "from": "cssstyle@>=0.2.3",
+ "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": {
- "cssom": {
- "version": "0.3.0",
- "from": "cssom@0.3.x"
+ "core-util-is": {
+ "version": "1.0.1",
+ "from": "core-util-is@~1.0.0"
+ },
+ "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"
+ },
+ "debuglog": {
+ "version": "0.0.2",
+ "from": "debuglog@0.0.2",
+ "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz"
}
}
},
- "contextify": {
- "version": "0.1.7",
- "from": "contextify@0.1.x",
+ "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": {
- "bindings": {
- "version": "1.2.0",
- "from": "bindings@*"
- },
- "nan": {
- "version": "0.8.0",
- "from": "nan@~0.8.0"
+ "sax": {
+ "version": "0.6.0",
+ "from": "sax@>=0.1.1"
}
}
- }
- }
- },
- "mime": {
- "version": "1.2.11",
- "from": "mime@~1.2.7"
- },
- "ms": {
- "version": "0.1.0",
- "from": "ms@~0.1.0"
- },
- "q": {
- "version": "0.8.12",
- "from": "q@~0.8.6"
- },
- "request": {
- "version": "2.10.0",
- "from": "request@~2.10.0"
- },
- "tough-cookie": {
- "version": "0.9.15",
- "from": "tough-cookie@~0.9.13",
- "dependencies": {
- "punycode": {
- "version": "1.2.4",
- "from": "punycode@~1.2.3"
- }
- }
- },
- "ws": {
- "version": "0.4.31",
- "from": "ws@~0.4.21",
- "dependencies": {
- "commander": {
- "version": "0.6.1",
- "from": "commander@~0.6.1"
- },
- "nan": {
- "version": "0.3.2",
- "from": "nan@~0.3.0"
},
- "tinycolor": {
- "version": "0.0.1",
- "from": "tinycolor@0.x"
- },
- "options": {
- "version": "0.0.5",
- "from": "options@>=0.0.5"
+ "source-map-support": {
+ "version": "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": {
+ "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": {
+ "amdefine": {
+ "version": "0.1.0",
+ "from": "amdefine@>=0.0.4"
+ }
+ }
+ }
+ }
}
}
}
}
},
- "jshint": {
- "version": "2.4.4",
- "from": "jshint@2.4.x",
+ "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"
+ },
+ "deprecate": {
+ "version": "0.1.0",
+ "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": {
- "shelljs": {
- "version": "0.1.4",
- "from": "shelljs@0.1.x"
- },
- "cli": {
- "version": "0.4.5",
- "from": "cli@0.4.x",
+ "form-data": {
+ "version": "0.0.7",
+ "from": "form-data@~0.0.3",
"dependencies": {
- "glob": {
- "version": "3.2.9",
- "from": "glob@>= 3.1.4",
+ "combined-stream": {
+ "version": "0.0.4",
+ "from": "combined-stream@~0.0.4",
"dependencies": {
- "inherits": {
- "version": "2.0.1",
- "from": "inherits@2"
+ "delayed-stream": {
+ "version": "0.0.5",
+ "from": "delayed-stream@0.0.5"
}
}
+ },
+ "async": {
+ "version": "0.1.22",
+ "from": "async@~0.1.9"
}
}
},
- "minimatch": {
- "version": "0.2.14",
- "from": "minimatch@0.x.x",
+ "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": {
- "lru-cache": {
- "version": "2.5.0",
- "from": "lru-cache@2"
- },
- "sigmund": {
- "version": "1.0.0",
- "from": "sigmund@~1.0.0"
+ "keypress": {
+ "version": "0.1.0",
+ "from": "keypress@0.1.x"
}
}
- },
- "htmlparser2": {
- "version": "3.3.0",
- "from": "htmlparser2@3.3.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": {
- "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"
+ "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"
},
- "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",
+ "ws": {
+ "version": "0.4.32",
+ "from": "ws@0.4.x",
"dependencies": {
- "core-util-is": {
- "version": "1.0.1",
- "from": "core-util-is@~1.0.0"
+ "commander": {
+ "version": "2.1.0",
+ "from": "commander@~2.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz"
},
- "isarray": {
- "version": "0.0.1",
- "from": "isarray@0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ "nan": {
+ "version": "1.0.0",
+ "from": "nan@~1.0.0"
},
- "string_decoder": {
- "version": "0.10.25-1",
- "from": "string_decoder@~0.10.x"
+ "tinycolor": {
+ "version": "0.0.1",
+ "from": "tinycolor@0.x"
},
- "inherits": {
- "version": "2.0.1",
- "from": "inherits@~2.0.1"
+ "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"
}
}
}
}
},
- "console-browserify": {
- "version": "0.1.6",
- "from": "console-browserify@0.1.x"
+ "policyfile": {
+ "version": "0.0.4",
+ "from": "policyfile@0.0.4",
+ "resolved": "https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz"
},
- "exit": {
- "version": "0.1.2",
- "from": "exit@0.1.x"
+ "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"
}
}
},
- "html5": {
- "version": "0.3.13",
- "from": "html5@0.3.13",
+ "underscore": {
+ "version": "1.4.4",
+ "from": "underscore@1.4.x",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz"
+ },
+ "underscore.string": {
+ "version": "2.3.3",
+ "from": "underscore.string@~2.3.3"
+ },
+ "winston": {
+ "version": "0.7.3",
+ "from": "winston@0.7.x",
"dependencies": {
- "jsdom": {
- "version": "0.10.5",
- "from": "jsdom@>= 0.6.0",
+ "cycle": {
+ "version": "1.0.3",
+ "from": "cycle@1.0.x"
+ },
+ "eyes": {
+ "version": "0.1.8",
+ "from": "eyes@0.1.x"
+ },
+ "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": {
- "htmlparser2": {
- "version": "3.7.1",
- "from": "htmlparser2@>= 3.1.5 <4",
+ "form-data": {
+ "version": "0.0.10",
+ "from": "form-data@~0.0.3",
"dependencies": {
- "domhandler": {
- "version": "2.2.0",
- "from": "domhandler@2.2"
- },
- "domutils": {
- "version": "1.4.3",
- "from": "domutils@1.4"
- },
- "domelementtype": {
- "version": "1.1.1",
- "from": "domelementtype@1"
- },
- "readable-stream": {
- "version": "1.1.13-1",
- "from": "readable-stream@1.1",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13-1.tgz",
+ "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": {
- "core-util-is": {
- "version": "1.0.1",
- "from": "core-util-is@~1.0.0"
- },
- "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"
- },
- "inherits": {
- "version": "2.0.1",
- "from": "inherits@~2.0.1"
+ "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"
},
- "entities": {
- "version": "1.0.0",
- "from": "entities@1.0"
+ "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"
}
}
},
- "nwmatcher": {
- "version": "1.3.3",
- "from": "nwmatcher@~1.3.2"
+ "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"
},
- "xmlhttprequest": {
- "version": "1.6.0",
- "from": "xmlhttprequest@>=1.5.0"
+ "tunnel-agent": {
+ "version": "0.2.0",
+ "from": "tunnel-agent@~0.2.0"
},
- "cssom": {
- "version": "0.3.0",
- "from": "cssom@~0.3.0"
+ "json-stringify-safe": {
+ "version": "3.0.0",
+ "from": "json-stringify-safe@~3.0.0"
},
- "cssstyle": {
- "version": "0.2.11",
- "from": "cssstyle@~0.2.9"
+ "qs": {
+ "version": "0.5.6",
+ "from": "qs@~0.5.4"
+ }
+ }
+ },
+ "stack-trace": {
+ "version": "0.0.9",
+ "from": "stack-trace@0.0.x"
+ }
+ }
+ },
+ "xtuple-linguist": {
+ "version": "0.1.0",
+ "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": {
+ "moment": {
+ "version": "2.4.0",
+ "from": "moment@2.4.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.4.0.tgz"
},
- "contextify": {
- "version": "0.1.7",
- "from": "contextify@~0.1.5",
- "dependencies": {
- "bindings": {
- "version": "1.2.0",
- "from": "bindings@*"
- },
- "nan": {
- "version": "0.8.0",
- "from": "nan@~0.8.0"
- }
- }
+ "underscore": {
+ "version": "1.5.2",
+ "from": "underscore@1.5.2"
}
}
},
- "opts": {
- "version": "1.2.2",
- "from": "opts@~1.2.1"
+ "moment": {
+ "version": "2.6.0",
+ "from": "moment@2.6.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.6.0.tgz"
},
- "html5-entities": {
- "version": "0.5.1",
- "from": "html5-entities@~0.5.0"
+ "underscore": {
+ "version": "1.6.0",
+ "from": "underscore@1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
}
}
},
- "nodemon": {
- "version": "1.0.17",
- "from": "nodemon@~1.0.15",
+ "zombie": {
+ "version": "1.4.1",
+ "from": "zombie@1.4.x",
+ "resolved": "https://registry.npmjs.org/zombie/-/zombie-1.4.1.tgz",
"dependencies": {
- "update-notifier": {
- "version": "0.1.8",
- "from": "update-notifier@~0.1.7",
+ "eventsource": {
+ "version": "0.0.10",
+ "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": {
- "request": {
- "version": "2.27.0",
- "from": "request@~2.27.0",
- "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.2",
- "from": "forever-agent@~0.5.0"
- },
- "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"
- }
- }
- },
- "hawk": {
- "version": "1.0.0",
- "from": "hawk@~1.0.0",
- "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-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.0"
- },
- "mime": {
- "version": "1.2.11",
- "from": "mime@~1.2.9",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
- },
- "form-data": {
- "version": "0.1.2",
- "from": "form-data@~0.1.0",
- "dependencies": {
- "combined-stream": {
- "version": "0.0.4",
- "from": "combined-stream@~0.0.4",
- "dependencies": {
- "delayed-stream": {
- "version": "0.0.5",
- "from": "delayed-stream@0.0.5"
- }
- }
- }
- }
- }
- }
+ "htmlparser": {
+ "version": "1.7.7",
+ "from": "htmlparser@1.x"
},
- "configstore": {
- "version": "0.2.3",
- "from": "configstore@~0.2.2",
+ "cssom": {
+ "version": "0.2.5",
+ "from": "cssom@0.2.x"
+ },
+ "cssstyle": {
+ "version": "0.2.14",
+ "from": "cssstyle@>=0.2.3",
"dependencies": {
- "mkdirp": {
- "version": "0.3.5",
- "from": "mkdirp@~0.3.5"
- },
- "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"
- }
- }
- },
- "osenv": {
- "version": "0.0.3",
- "from": "osenv@0.0.3",
- "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.0.3.tgz"
- },
- "graceful-fs": {
- "version": "2.0.3",
- "from": "graceful-fs@~2.0.1"
- },
- "uuid": {
- "version": "1.4.1",
- "from": "uuid@~1.4.1"
- },
- "object-assign": {
- "version": "0.1.2",
- "from": "object-assign@~0.1.1"
+ "cssom": {
+ "version": "0.3.0",
+ "from": "cssom@0.3.x"
}
}
},
- "semver": {
- "version": "2.1.0",
- "from": "semver@~2.1.0"
- },
- "chalk": {
- "version": "0.4.0",
- "from": "chalk@~0.4.0",
+ "contextify": {
+ "version": "0.1.8",
+ "from": "contextify@0.1.x",
"dependencies": {
- "has-color": {
- "version": "0.1.7",
- "from": "has-color@~0.1.0",
- "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz"
+ "bindings": {
+ "version": "1.2.1",
+ "from": "bindings@*",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
},
- "ansi-styles": {
+ "nan": {
"version": "1.0.0",
- "from": "ansi-styles@~1.0.0"
- },
- "strip-ansi": {
- "version": "0.1.1",
- "from": "strip-ansi@~0.1.0"
+ "from": "nan@~1.0.0"
}
}
}
}
},
- "minimatch": {
- "version": "0.2.14",
- "from": "minimatch@~0.2.14",
+ "mime": {
+ "version": "1.2.11",
+ "from": "mime@~1.2.7"
+ },
+ "ms": {
+ "version": "0.1.0",
+ "from": "ms@~0.1.0"
+ },
+ "q": {
+ "version": "0.8.12",
+ "from": "q@~0.8.6",
+ "resolved": "https://registry.npmjs.org/q/-/q-0.8.12.tgz"
+ },
+ "request": {
+ "version": "2.10.0",
+ "from": "request@~2.10.0"
+ },
+ "tough-cookie": {
+ "version": "0.9.15",
+ "from": "tough-cookie@~0.9.13",
"dependencies": {
- "lru-cache": {
- "version": "2.5.0",
- "from": "lru-cache@2"
+ "punycode": {
+ "version": "1.3.1",
+ "from": "punycode@>=0.2.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.1.tgz"
+ }
+ }
+ },
+ "ws": {
+ "version": "0.4.32",
+ "from": "ws@~0.4.21",
+ "dependencies": {
+ "commander": {
+ "version": "2.1.0",
+ "from": "commander@~2.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz"
},
- "sigmund": {
+ "nan": {
"version": "1.0.0",
- "from": "sigmund@~1.0.0"
+ "from": "nan@~1.0.0"
+ },
+ "tinycolor": {
+ "version": "0.0.1",
+ "from": "tinycolor@0.x"
+ },
+ "options": {
+ "version": "0.0.5",
+ "from": "options@>=0.0.5"
}
}
}
"author": "xTuple <dev@xtuple.com>",
"name": "xtuple",
"description": "xTuple Enterprise Resource Planning Mobile-Web client",
- "version": "4.6.0",
+ "version": "4.7.0-beta",
"repository": {
"type": "git",
"url": "https://github.com/xtuple/xtuple.git"
"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": {
"chai": "1.5.x",
- "jshint": "2.4.x",
"mocha": "1.9.x",
- "require-uncache": "0.0.x",
"html5": "0.3.13",
+ "jshint": "2.4.x",
"zombie": "1.4.x",
- "csslint": "~0.10.0",
- "xtuple-documentation": "~0.0.1",
- "nodemon": "~1.0.15"
+ "nodemon": "~1.0.15",
+ "csslint": "~0.10.0"
},
"optionalDependencies": {
"xtuple-query": "~1.0.0",
"googleapis": "~0.4.6"
},
"engines": {
- "node": "0.8.x"
+ "node": "^0.10"
},
"main": "node-datasource/main.js",
"scripts": {
var fs = require("fs"),
program = require("commander"),
path = require("path"),
- buildDatabaseUtil = require("./lib/build_database_util");
+ explodeManifest = require("./lib/util/process_manifest").explodeManifest;
program
.option('-m, --manifest [/path/to/manifest.js]', 'Location of manifest file.')
.option('-n, --name [inventory_upgrade.sql]', 'Name of destination file.')
.parse(process.argv);
- // the path is not relative if it starts with a slash
- var manifestPath = program.manifest.substring(0, 1) === '/' ?
- program.manifest :
- path.join(process.cwd(), program.manifest);
+ var manifestFilename = path.resolve(process.cwd(), program.manifest);
- buildDatabaseUtil.explodeManifest(manifestPath, {}, function (err, contents) {
+ explodeManifest({manifestFilename: manifestFilename}, function (err, contents) {
var outputFile;
if (err) {
console.log("error: ", err);
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}"
sudo nvm alias default $NODE_VERSION
sudo nvm alias xtuple $NODE_VERSION
+ # use latest 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 ""
var _ = require('underscore'),
async = require('async'),
buildDatabase = require("./build_database"),
- buildDatabaseUtil = require("./build_database_util"),
+ buildDictionary = require("./build_dictionary"),
buildClient = require("./build_client").buildClient,
+ defaultExtensions = require("./util/default_extensions").extensions,
dataSource = require('../../node-datasource/lib/ext/datasource').dataSource,
exec = require('child_process').exec,
fs = require('fs'),
+ initDatabase = require("./util/init_database").initDatabase,
+ inspectDatabaseExtensions = require("./util/inspect_database").inspectDatabaseExtensions,
npm = require('npm'),
path = require('path'),
- unregister = buildDatabaseUtil.unregister,
+ unregister = require("./util/unregister").unregister,
winston = require('winston');
/*
var creds;
+ var buildAll = function (specs, creds, buildAllCallback) {
+ async.series([
+ function (done) {
+ // step 0: init the database, if requested
+
+ if (specs.length === 1 &&
+ specs[0].initialize &&
+ (specs[0].backup || specs[0].source)) {
+
+ // The user wants to initialize the database first (i.e. Step 0)
+ // Do that, then call this function again
+ initDatabase(specs[0], creds, function (err, res) {
+ specs[0].wasInitialized = true;
+ done(err, res);
+ });
+ return;
+ } else {
+ done();
+ }
+
+ },
+ function (done) {
+ // step 1: npm install extension if necessary
+ // an alternate approach would be only npm install these
+ // extensions on an npm install.
+ var allExtensions = _.reduce(specs, function (memo, spec) {
+ memo.push(spec.extensions);
+ return _.flatten(memo);
+ }, []);
+ var npmExtensions = _.filter(allExtensions, function (extName) {
+ return extName && extName.indexOf("node_modules") >= 0;
+ });
+ if (npmExtensions.length === 0) {
+ done();
+ return;
+ }
+ npm.load(function (err, res) {
+ if (err) {
+ done(err);
+ return;
+ }
+ npm.on("log", function (message) {
+ // log the progress of the installation
+ console.log(message);
+ });
+ async.map(npmExtensions, function (extName, next) {
+ npm.commands.install([path.basename(extName)], next);
+ }, done);
+ });
+ },
+ function (done) {
+ // step 2: build the client
+ buildClient(specs, done);
+ },
+ function (done) {
+ // step 3: build the database
+ buildDatabase.buildDatabase(specs, creds, function (databaseErr, databaseRes) {
+ if (databaseErr) {
+ buildAllCallback(databaseErr);
+ return;
+ }
+ var returnMessage = "\n";
+ _.each(specs, function (spec) {
+ returnMessage += "Database: " + spec.database + '\nDirectories:\n';
+ _.each(spec.extensions, function (ext) {
+ returnMessage += ' ' + ext + '\n';
+ });
+ });
+ 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 - 2]);
+ });
+ };
exports.build = function (options, callback) {
var buildSpecs = {},
getRegisteredExtensions = function (database, callback) {
var credsClone = JSON.parse(JSON.stringify(creds));
credsClone.database = database;
- buildDatabaseUtil.inspectDatabaseExtensions(credsClone, function (err, paths) {
+ inspectDatabaseExtensions(credsClone, function (err, paths) {
callback(null, {
extensions: paths,
database: database,
});
});
},
- buildAll = function (specs, creds, buildAllCallback) {
- async.series([
- function (done) {
- // step 0: init the database, if requested
-
- if (specs.length === 1 &&
- specs[0].initialize &&
- (specs[0].backup || specs[0].source)) {
-
- // The user wants to initialize the database first (i.e. Step 0)
- // Do that, then call this function again
- buildDatabaseUtil.initDatabase(specs[0], creds, function (err, res) {
- specs[0].wasInitialized = true;
- done(err, res);
- });
- return;
- } else {
- done();
- }
-
- },
- function (done) {
- // step 1: npm install extension if necessary
- // an alternate approach would be only npm install these
- // extensions on an npm install.
- var allExtensions = _.reduce(specs, function (memo, spec) {
- memo.push(spec.extensions);
- return _.flatten(memo);
- }, []);
- var npmExtensions = _.filter(allExtensions, function (extName) {
- return extName && extName.indexOf("node_modules") >= 0;
- });
- if (npmExtensions.length === 0) {
- done();
- return;
- }
- npm.load(function (err, res) {
- if (err) {
- done(err);
- return;
- }
- npm.on("log", function (message) {
- // log the progress of the installation
- console.log(message);
- });
- async.map(npmExtensions, function (extName, next) {
- npm.commands.install([path.basename(extName)], next);
- }, done);
- });
- },
- function (done) {
- // step 2: build the client
- buildClient(specs, done);
- },
- function (done) {
- // step 3: build the database
- buildDatabase.buildDatabase(specs, creds, function (databaseErr, databaseRes) {
- if (databaseErr) {
- buildAllCallback(databaseErr);
- return;
- }
- var returnMessage = "\n";
- _.each(specs, function (spec) {
- returnMessage += "Database: " + spec.database + '\nDirectories:\n';
- _.each(spec.extensions, function (ext) {
- returnMessage += ' ' + ext + '\n';
- });
- });
- done(null, "Build succeeded." + returnMessage);
- });
- }
- ], function (err, results) {
- buildAllCallback(err, results && results[results.length - 1]);
- });
- },
config;
if (options.config) {
// an unmobilized build
buildSpecs.extensions = options.extension ?
[options.extension] :
- buildDatabaseUtil.defaultExtensions;
+ defaultExtensions;
}
buildSpecs.initialize = true;
buildSpecs.keepSql = options.keepSql;
return;
}
fs.readFile(path.join(__dirname, "build", extName + ".css"), "utf8", function (err, cssCode) {
- // get the extension version from the database manifest file
- fs.readFile(path.join(extPath, "database/source/manifest.js"), "utf8", function (err, manifestContents) {
- if (err) {
- callback(err);
- return;
- }
- var manifestDetails = JSON.parse(manifestContents);
- if (!manifestDetails.version) {
- // if the extensions don't declare their version, default to the package version
- fs.readFile(path.join(__dirname, "../../package.json"), "utf8", function (err, packageJson) {
- if (err) {
- callback(err);
- return;
- }
- var packageDetails = JSON.parse(packageJson);
- callback(null, constructQuery(cssCode, extName, packageDetails.version, "css") +
- constructQuery(jsCode, extName, packageDetails.version, "js"));
- });
-
- } else {
- callback(null, constructQuery(cssCode, extName, manifestDetails.version, "css") +
- constructQuery(jsCode, extName, manifestDetails.version, "js"));
- }
- });
+ var version;
+ if (fs.existsSync(path.resolve(extPath, "package.json"))) {
+ version = require(path.resolve(extPath, "package.json")).version;
+ } else {
+ version = JSON.parse(fs.readFileSync(path.resolve(extPath, "database/source/manifest.js"))).version;
+ }
+ if (!version) {
+ // if the extensions don't declare their version, default to the package version
+ version = require(path.resolve(__dirname, "../../package.json")).version;
+ }
+ callback(null, constructQuery(cssCode, extName, version, "css") +
+ constructQuery(jsCode, extName, version, "js"));
});
});
}
var async = require('async'),
dataSource = require('../../node-datasource/lib/ext/datasource').dataSource,
- buildDatabaseUtil = require('./build_database_util'),
exec = require('child_process').exec,
+ explodeManifest = require("./util/process_manifest").explodeManifest,
fs = require('fs'),
ormInstaller = require('./orm'),
dictionaryBuilder = require('./build_dictionary'),
path = require('path'),
pg = require('pg'),
os = require('os'),
+ sendToDatabase = require("./util/send_to_database").sendToDatabase,
winston = require('winston');
(function () {
isPublicExtension = extension.indexOf("xtuple-extensions") >= 0,
isPrivateExtension = extension.indexOf("private-extensions") >= 0,
isNpmExtension = baseName.indexOf("xtuple-") >= 0,
+ isExtension = !isFoundation && !isLibOrm && !isApplicationCore,
dbSourceRoot = (isFoundation || isFoundationExtension) ? extension :
isLibOrm ? path.join(extension, "source") :
path.join(extension, "database/source"),
manifestOptions = {
+ manifestFilename: path.resolve(dbSourceRoot, "manifest.js"),
+ extensionPath: isExtension ?
+ path.resolve(dbSourceRoot, "../../") :
+ undefined,
useFrozenScripts: spec.frozen,
useFoundationScripts: baseName.indexOf('inventory') >= 0 ||
baseName.indexOf('manufacturing') >= 0 ||
baseName.indexOf('distribution') >= 0,
- registerExtension: !isFoundation && !isLibOrm && !isApplicationCore,
+ registerExtension: isExtension,
runJsInit: !isFoundation && !isLibOrm,
wipeViews: isApplicationCore && spec.wipeViews,
extensionLocation: isCoreExtension ? "/core-extensions" :
isNpmExtension ? "npm" : "not-applicable"
};
- buildDatabaseUtil.explodeManifest(path.join(dbSourceRoot, "manifest.js"),
- manifestOptions, extensionCallback);
+ explodeManifest(manifestOptions, extensionCallback);
};
// We also need to get the sql that represents the queries to generate
// on the case of error.
allSql = "\\set ON_ERROR_STOP TRUE;\n" + allSql;
- if (spec.wasInitialized && !_.isEqual(extensions, ["foundation-database"])) {
- // give the admin user every extension by default
- allSql = allSql + "insert into xt.usrext (usrext_usr_username, usrext_ext_id) " +
- "select '" + creds.username +
- "', ext_id from xt.ext where ext_location = '/core-extensions' and ext_name NOT LIKE 'oauth2';";
- }
-
winston.info("Applying build to database " + spec.database);
credsClone.database = spec.database;
- buildDatabaseUtil.sendToDatabase(allSql, credsClone, spec, function (err, res) {
+ sendToDatabase(allSql, credsClone, spec, function (err, res) {
if (spec.populateData && creds.encryptionKeyFile) {
var populateSql = "DO $$ XT.disableLocks = true; $$ language plv8;";
var encryptionKey = fs.readFileSync(path.resolve(__dirname, "../../node-datasource", creds.encryptionKeyFile), "utf8");
+++ /dev/null
-/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
-regexp:true, undef:true, strict:true, trailing:true, white:true */
-/*global _:true */
-
-(function () {
- "use strict";
-
- var _ = require('underscore'),
- async = require('async'),
- exec = require('child_process').exec,
- fs = require('fs'),
- os = require('os'),
- path = require('path'),
- dataSource = require('../../node-datasource/lib/ext/datasource').dataSource,
- winston = require('winston');
-
- var defaultExtensions = [
- path.join(__dirname, '../../foundation-database'),
- path.join(__dirname, '../../lib/orm'),
- path.join(__dirname, '../../enyo-client'),
- path.join(__dirname, '../../enyo-client/extensions/source/crm'),
- path.join(__dirname, '../../enyo-client/extensions/source/project'),
- path.join(__dirname, '../../enyo-client/extensions/source/sales'),
- path.join(__dirname, '../../enyo-client/extensions/source/billing'),
- path.join(__dirname, '../../enyo-client/extensions/source/purchasing'),
- path.join(__dirname, '../../enyo-client/extensions/source/oauth2')
- ];
-
- var convertFromMetasql = function (content, filename, defaultSchema) {
- var lines = content.split("\n"),
- schema = defaultSchema ? "'" + defaultSchema + "'" : "NULL",
- group,
- i = 2,
- name,
- notes = "",
- grade = 0,
- deleteSql,
- insertSql;
-
- if (lines[0].indexOf("-- Group: ") !== 0 ||
- lines[1].indexOf("-- Name: ") !== 0 ||
- lines[2].indexOf("-- Notes:") !== 0) {
- throw new Error("Improperly formatted metasql: " + filename);
- }
- group = lines[0].substring("-- Group: ".length).trim();
- name = lines[1].substring("-- Name: ".length).trim();
- while (lines[i].indexOf("--") === 0) {
- notes = notes + lines[i].substring(2) + "\n";
- i++;
- }
- notes = notes.substring(" Notes:".length);
- if (notes.indexOf("must be grade 10") >= 0) {
- grade = 10;
- }
-
- insertSql = "select saveMetasql (" +
- "'" + group + "'," +
- "'" + name + "'," +
- "$$" + notes + "$$," +
- "$$" + content + "$$," +
- "true, " + schema + ", " + grade + ");";
-
- return insertSql;
- };
-
- var convertFromReport = function (content, filename, defaultSchema) {
- var lines = content.split("\n"),
- name,
- grade = "0",
- tableName = defaultSchema ? defaultSchema + ".pkgreport" : "report",
- description,
- disableSql,
- updateSql,
- insertSql,
- enableSql;
-
- if (lines[3].indexOf(" <name>") !== 0 ||
- lines[4].indexOf(" <description>") !== 0) {
- throw new Error("Improperly formatted report");
- }
- name = lines[3].substring(" <name>".length).trim();
- name = name.substring(0, name.indexOf("<"));
- description = lines[4].substring(" <description>".length).trim();
- description = description.substring(0, description.indexOf("<"));
- if (lines[5].indexOf("grade") >= 0) {
- grade = lines[5].substring(" <grade>".length).trim();
- grade = grade.substring(0, grade.indexOf("<"));
- }
-
- disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
-
- insertSql = "insert into " + tableName + " (report_name, report_descrip, " +
- "report_source, report_loaddate, report_grade) select " +
- "'" + name + "'," +
- "$$" + description + "$$," +
- "$$" + content + "$$," +
- "now(), " + grade +
- " where not exists (select c.report_id from " + tableName + " c " +
- "where report_name = '" + name +
- "' and report_grade = " + grade + ");";
-
- updateSql = "update " + tableName + " set " +
- " report_descrip = $$" + description +
- "$$, report_source = $$" + content +
- "$$, report_loaddate = now() " +
- "where report_name = '" + name +
- "' and report_grade = " + grade + ";";
-
- enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
-
- return disableSql + insertSql + updateSql + enableSql;
- };
-
- var convertFromScript = function (content, filename, defaultSchema) {
- var name = path.basename(filename, '.js'),
- tableName = defaultSchema ? defaultSchema + ".pkgscript" : "unknown",
- notes = "", //"xtMfg package",
- disableSql,
- insertSql,
- updateSql,
- enableSql;
-
- disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
-
- insertSql = "insert into " + tableName + " (script_name, script_order, script_enabled, " +
- "script_source, script_notes) select " +
- "'" + name + "', 0, TRUE, " +
- "$$" + content + "$$," +
- "'" + notes + "'" +
- " where not exists (select c.script_id from " + tableName + " c " +
- "where script_name = '" + name + "');";
-
- updateSql = "update " + tableName + " set " +
- "script_name = '" + name + "', script_order = 0, script_enabled = TRUE, " +
- "script_source = $$" + content +
- "$$, script_notes = '" + notes + "' " +
- "where script_name = '" + name + "';";
-
- enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
-
- return disableSql + insertSql + updateSql + enableSql;
- };
-
- var convertFromUiform = function (content, filename, defaultSchema) {
- var name = path.basename(filename, '.ui'),
- tableName = defaultSchema ? defaultSchema + ".pkguiform" : "unknown",
- notes = "", //"xtMfg package",
- disableSql,
- insertSql,
- updateSql,
- enableSql;
-
- disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
-
- insertSql = "insert into " + tableName + " (uiform_name, uiform_order, uiform_enabled, " +
- "uiform_source, uiform_notes) select " +
- "'" + name + "', 0, TRUE, " +
- "$$" + content + "$$," +
- "'" + notes + "' " +
- " where not exists (select c.uiform_id from " + tableName + " c " +
- "where uiform_name = '" + name + "');";
-
- updateSql = "update " + tableName + " set uiform_name = '" +
- name + "', uiform_order = 0, uiform_enabled = TRUE, " +
- "uiform_source = $$" + content + "$$, uiform_notes = '" + notes + "' " +
- "where uiform_name = '" + name + "';";
-
- enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
-
- return disableSql + insertSql + updateSql + enableSql;
- };
-
- var conversionMap = {
- mql: convertFromMetasql,
- xml: convertFromReport,
- js: convertFromScript,
- ui: convertFromUiform,
- sql: function (content) {
- // no op
- return content;
- }
- };
-
- var explodeManifest = function (manifestFilename, options, manifestCallback) {
- var dbSourceRoot = path.dirname(manifestFilename);
- //
- // Step 2:
- // Read the manifest files.
- //
- if (!fs.existsSync(manifestFilename)) {
- // error condition: no manifest file
- manifestCallback("Cannot find manifest " + manifestFilename);
- return;
- }
- fs.readFile(manifestFilename, "utf8", function (err, manifestString) {
- var manifest,
- databaseScripts,
- extraManifestPath,
- defaultSchema,
- extraManifest,
- extraManifestScripts,
- alterPaths = dbSourceRoot.indexOf("foundation-database") < 0,
- extensionName,
- loadOrder,
- extensionComment;
-
- try {
- manifest = JSON.parse(manifestString);
- extensionName = manifest.name;
- extensionComment = manifest.comment;
- databaseScripts = manifest.databaseScripts;
- defaultSchema = manifest.defaultSchema;
- loadOrder = manifest.loadOrder || 999;
-
- } catch (error) {
- // error condition: manifest file is not properly formatted
- manifestCallback("Manifest is not valid JSON" + manifestFilename);
- return;
- }
-
- //
- // Step 2b:
- //
-
- // supported use cases:
-
- // 1. add mobilized inventory to quickbooks
- // need the frozen_manifest, the foundation/manifest, and the mobile manifest
- // -e ../private-extensions/source/inventory -f
- // useFrozenScripts, useFoundationScripts
-
- // 2. add mobilized inventory to masterref (foundation inventory is already there)
- // need the the foundation/manifest and the mobile manifest
- // -e ../private-extensions/source/inventory
- // useFoundationScripts
-
- // 3. add unmobilized inventory to quickbooks
- // need the frozen_manifest and the foundation/manifest
- // -e ../private-extensions/source/inventory/foundation-database -f
- // useFrozenScripts (useFoundationScripts already taken care of by -e path)
-
- // 4. upgrade unmobilized inventory
- // not sure if this is necessary, but it would look like
- // -e ../private-extensions/source/inventory/foundation-database
-
- if (options.useFoundationScripts) {
- extraManifest = JSON.parse(fs.readFileSync(path.join(dbSourceRoot, "../../foundation-database/manifest.js")));
- defaultSchema = defaultSchema || extraManifest.defaultSchema;
- extraManifestScripts = extraManifest.databaseScripts;
- extraManifestScripts = _.map(extraManifestScripts, function (path) {
- return "../../foundation-database/" + path;
- });
- databaseScripts.unshift(extraManifestScripts);
- databaseScripts = _.flatten(databaseScripts);
- }
- if (options.useFrozenScripts) {
- // Frozen files are not idempotent and should only be run upon first registration
- extraManifestPath = alterPaths ?
- path.join(dbSourceRoot, "../../foundation-database/frozen_manifest.js") :
- path.join(dbSourceRoot, "frozen_manifest.js");
-
- extraManifest = JSON.parse(fs.readFileSync(extraManifestPath));
- defaultSchema = defaultSchema || extraManifest.defaultSchema;
- extraManifestScripts = extraManifest.databaseScripts;
- if (alterPaths) {
- extraManifestScripts = _.map(extraManifestScripts, function (path) {
- return "../../foundation-database/" + path;
- });
- }
- databaseScripts.unshift(extraManifestScripts);
- databaseScripts = _.flatten(databaseScripts);
- }
-
- //
- // Step 3:
- // Concatenate together all the files referenced in the manifest.
- //
- var getScriptSql = function (filename, scriptCallback) {
- var fullFilename = path.join(dbSourceRoot, filename);
- if (!fs.existsSync(fullFilename)) {
- // error condition: script referenced in manifest.js isn't there
- scriptCallback(path.join(dbSourceRoot, filename) + " does not exist");
- return;
- }
- fs.readFile(fullFilename, "utf8", function (err, scriptContents) {
- // error condition: can't read script
- if (err) {
- scriptCallback(err);
- return;
- }
- var beforeNoticeSql = "do $$ BEGIN RAISE NOTICE 'Loading file " + path.basename(fullFilename) +
- "'; END $$ language plpgsql;\n",
- extname = path.extname(fullFilename).substring(1);
-
- // convert special files: metasql, uiforms, reports, uijs
- scriptContents = conversionMap[extname](scriptContents, fullFilename, defaultSchema);
- //
- // Allow inclusion of js files in manifest. If it is a js file,
- // use plv8 to execute it.
- //
- //if (fullFilename.substring(fullFilename.length - 2) === 'js') {
- // this isn't quite working yet
- // http://adpgtech.blogspot.com/2013/03/loading-useful-modules-in-plv8.html
- // put in lib/orm's manifest.js: "../../tools/lib/underscore/underscore-min.js",
- // scriptContents = "do $$ " + scriptContents + " $$ language plv8;";
- //}
-
- //
- // Incorrectly-ended sql files (i.e. no semicolon) make for unhelpful error messages
- // when we concatenate 100's of them together. Guard against these.
- //
- scriptContents = scriptContents.trim();
- if (scriptContents.charAt(scriptContents.length - 1) !== ';') {
- // error condition: script is improperly formatted
- scriptCallback("Error: " + fullFilename + " contents do not end in a semicolon.");
- }
-
- scriptCallback(null, '\n' + scriptContents);
- });
- };
- async.mapSeries(databaseScripts || [], getScriptSql, function (err, scriptSql) {
- var registerSql,
- dependencies;
-
- if (err) {
- manifestCallback(err);
- return;
- }
- // each String of the scriptContents is the concatenated SQL for the script.
- // join these all together into a single string for the whole extension.
- var extensionSql = _.reduce(scriptSql, function (memo, script) {
- return memo + script;
- }, "");
-
- if (options.registerExtension) {
- // register extension and dependencies
- extensionSql = 'do $$ plv8.elog(NOTICE, "About to register extension ' +
- extensionName + '"); $$ language plv8;\n' + extensionSql;
-
- registerSql = "select xt.register_extension('%@', '%@', '%@', '', %@);\n"
- .f(extensionName, extensionComment, options.extensionLocation, loadOrder);
-
- var grantExtToAdmin = "select xt.grant_role_ext('ADMIN', '%@');\n"
- .f(extensionName);
-
- extensionSql = grantExtToAdmin + extensionSql;
-
- dependencies = manifest.dependencies || [];
- _.each(dependencies, function (dependency) {
- var dependencySql = "select xt.register_extension_dependency('%@', '%@');\n"
- .f(extensionName, dependency),
- grantDependToAdmin = "select xt.grant_role_ext('ADMIN', '%@');\n"
- .f(dependency);
-
- extensionSql = dependencySql + grantDependToAdmin + extensionSql;
- });
- extensionSql = registerSql + extensionSql;
- }
- if (options.runJsInit) {
- // unless it it hasn't yet been defined (ie. lib/orm),
- // running xt.js_init() is probably a good idea.
- extensionSql = "select xt.js_init();" + extensionSql;
- }
-
- if (options.wipeViews) {
- // If we want to pre-emptively wipe out the views, the best place to do it
- // is at the start of the core application code
- fs.readFile(path.join(__dirname, "../../enyo-client/database/source/delete_system_orms.sql"),
- function (err, wipeSql) {
- if (err) {
- manifestCallback(err);
- return;
- }
- extensionSql = wipeSql + extensionSql;
- manifestCallback(null, extensionSql);
- });
- } else {
- manifestCallback(null, extensionSql);
- }
-
- });
- //
- // End script installation code
- //
- });
- };
-
- var pathFromExtension = function (name, location) {
- if (location === '/core-extensions') {
- return path.join(__dirname, "/../../enyo-client/extensions/source/", name);
- } else if (location === '/xtuple-extensions') {
- return path.join(__dirname, "../../../xtuple-extensions/source", name);
- } else if (location === '/private-extensions') {
- return path.join(__dirname, "../../../private-extensions/source", name);
- } else if (location === 'npm') {
- return path.join(__dirname, "../../node_modules", name);
- }
- };
-
- //
- // Looks in a database to see which extensions are registered, and
- // tacks onto that list the core directories.
- //
- var inspectMobilizedDatabase = function (creds, done) {
- var extSql = "SELECT * FROM xt.ext ORDER BY ext_load_order";
- dataSource.query(extSql, creds, function (err, res) {
- if (err) {
- return done(err);
- }
-
- var paths = _.map(_.compact(res.rows), function (row) {
- return pathFromExtension(row.ext_name, row.ext_location);
- });
-
- paths.unshift(path.join(__dirname, "../../enyo-client")); // core path
- paths.unshift(path.join(__dirname, "../../lib/orm")); // lib path
- paths.unshift(path.join(__dirname, "../../foundation-database")); // foundation path
- done(null, _.compact(paths));
- });
- };
-
- var inspectUnmobilizedDatabase = function (creds, done) {
- var extSql = "select * from public.pkghead where pkghead_name in ('xtmfg', 'xwd');",
- editionMap = {
- xtmfg: ["inventory", "manufacturing"],
- xwd: ["inventory", "distribution"]
- };
- dataSource.query(extSql, creds, function (err, res) {
- if (err) {
- return done(err);
- }
- var extensions = _.unique(_.flatten(_.map(res.rows, function (row) {
- return _.map(editionMap[row.pkghead_name], function (ext) {
- return path.join(__dirname, "../../../private-extensions/source", ext);
- });
- })));
- done(err, defaultExtensions.concat(extensions));
- });
- };
-
- var inspectDatabaseExtensions = function (creds, done) {
- var isMobilizedSql = "select * from information_schema.tables where table_schema = 'xt' and table_name = 'ext';";
-
- dataSource.query(isMobilizedSql, creds, function (err, res) {
- if (res.rowCount === 0) {
- inspectUnmobilizedDatabase(creds, done);
- } else {
- inspectMobilizedDatabase(creds, done);
- }
- });
- };
-
- //
- // Step 0 (optional, triggered by flags), wipe out the database
- // and load it from scratch using pg_restore something.backup unless
- // we're building from source.
- //
- var initDatabase = function (spec, creds, callback) {
- var databaseName = spec.database,
- credsClone = JSON.parse(JSON.stringify(creds)),
- dropDatabase = function (done) {
- winston.info("Dropping database " + databaseName);
- // the calls to drop and create the database need to be run against the database "postgres"
- credsClone.database = "postgres";
- dataSource.query("drop database if exists " + databaseName + ";", credsClone, done);
- },
- createDatabase = function (done) {
- winston.info("Creating database " + databaseName);
- dataSource.query("create database " + databaseName + " template template1;", credsClone, done);
- },
- buildSchema = function (done) {
- 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);
- },
- 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);
- },
- // 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) {
- if (err) {
- console.log("ignoring restore db error", err);
- }
- done(null, res);
- });
- },
- finish = function (err, results) {
- if (err) {
- winston.error("init database error", err.message, err.stack, err);
- }
- callback(err, results);
- };
-
- if (spec.source) {
- async.series([
- dropDatabase,
- createDatabase,
- buildSchema,
- populateData
- ], finish);
- } else {
- async.series([
- dropDatabase,
- createDatabase,
- restoreBackup,
- function (done) {
- credsClone.database = databaseName;
- inspectDatabaseExtensions(credsClone, function (err, paths) {
- // in the case of a build-from-backup, we ignore any user desires and dictate the extensions
- spec.extensions = paths;
- done();
- });
- }
- ], finish);
- }
- };
-
-
- var sendToDatabase = function (query, credsClone, options, callback) {
- var filename = path.join(__dirname, "temp_query_" + credsClone.database + ".sql");
- fs.writeFile(filename, query, function (err) {
- if (err) {
- winston.error("Cannot write query to file");
- callback(err);
- return;
- }
- var psqlCommand = 'psql -d ' + credsClone.database +
- ' -U ' + credsClone.username +
- ' -h ' + credsClone.hostname +
- ' -p ' + credsClone.port +
- ' -f ' + filename +
- ' --single-transaction';
-
-
- /**
- * http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
- * "maxBuffer specifies the largest amount of data allowed on stdout or
- * stderr - if this value is exceeded then the child process is killed."
- */
- exec(psqlCommand, {maxBuffer: 40000 * 1024 /* 200x default */}, function (err, stdout, stderr) {
- if (err) {
- winston.error("Cannot install file ", filename);
- callback(err);
- return;
- }
- if (options.keepSql) {
- // do not delete the temp query file
- winston.info("SQL file kept as ", filename);
- callback();
- } else {
- fs.unlink(filename, function (err) {
- if (err) {
- winston.error("Cannot delete written query file");
- callback(err);
- }
- callback();
- });
- }
- });
- });
- };
-
- //
- // Another option: unregister the extension
- //
- var unregister = function (specs, creds, masterCallback) {
- var extension = path.basename(specs[0].extensions[0]),
- unregisterSql = ["delete from xt.usrext where usrext_id in " +
- "(select usrext_id from xt.usrext inner join xt.ext on usrext_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.grpext where grpext_id in " +
- "(select grpext_id from xt.grpext inner join xt.ext on grpext_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.clientcode where clientcode_id in " +
- "(select clientcode_id from xt.clientcode inner join xt.ext on clientcode_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.dict where dict_id in " +
- "(select dict_id from xt.dict inner join xt.ext on dict_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.extdep where extdep_id in " +
- "(select extdep_id from xt.extdep inner join xt.ext " +
- "on extdep_from_ext_id = ext_id or extdep_to_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.ext where ext_name = $1;"];
-
- if (extension.charAt(extension.length - 1) === "/") {
- // remove trailing slash if present
- extension = extension.substring(0, extension.length - 1);
- }
- winston.info("Unregistering extension:", extension);
- var unregisterEach = function (spec, callback) {
- var options = JSON.parse(JSON.stringify(creds));
- options.database = spec.database;
- options.parameters = [extension];
- var queryEach = function (sql, sqlCallback) {
- dataSource.query(sql, options, sqlCallback);
- };
- async.eachSeries(unregisterSql, queryEach, callback);
- };
- async.each(specs, unregisterEach, masterCallback);
- };
-
- exports.defaultExtensions = defaultExtensions;
- exports.inspectDatabaseExtensions = inspectDatabaseExtensions;
- exports.explodeManifest = explodeManifest;
- exports.initDatabase = initDatabase;
- exports.sendToDatabase = sendToDatabase;
- exports.unregister = unregister;
-}());
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, {
target: target
});
});
- };
+ }
};
async.map(stringsArray, processString, function (err, strings) {
extensionCallback(null, {
/**
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();
});
};
+ 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);
+ };
+
+
}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var path = require('path');
+
+ var convertFromMetasql = function (content, filename, defaultSchema) {
+ var lines = content.split("\n"),
+ schema = defaultSchema ? "'" + defaultSchema + "'" : "NULL",
+ group,
+ i = 2,
+ name,
+ notes = "",
+ grade = 0,
+ deleteSql,
+ insertSql;
+
+ if (lines[0].indexOf("-- Group: ") !== 0 ||
+ lines[1].indexOf("-- Name: ") !== 0 ||
+ lines[2].indexOf("-- Notes:") !== 0) {
+ throw new Error("Improperly formatted metasql: " + filename);
+ }
+ group = lines[0].substring("-- Group: ".length).trim();
+ name = lines[1].substring("-- Name: ".length).trim();
+ while (lines[i].indexOf("--") === 0) {
+ notes = notes + lines[i].substring(2) + "\n";
+ i++;
+ }
+ notes = notes.substring(" Notes:".length);
+ if (notes.indexOf("must be grade 10") >= 0) {
+ grade = 10;
+ }
+
+ insertSql = "select saveMetasql (" +
+ "'" + group + "'," +
+ "'" + name + "'," +
+ "$$" + notes + "$$," +
+ "$$" + content + "$$," +
+ "true, " + schema + ", " + grade + ");";
+
+ return insertSql;
+ };
+
+ var convertFromReport = function (content, filename, defaultSchema) {
+ var lines = content.split("\n"),
+ name,
+ grade = "0",
+ tableName = defaultSchema ? defaultSchema + ".pkgreport" : "report",
+ description,
+ disableSql,
+ updateSql,
+ insertSql,
+ enableSql;
+
+ if (lines[3].indexOf(" <name>") !== 0 ||
+ lines[4].indexOf(" <description>") !== 0) {
+ throw new Error("Improperly formatted report");
+ }
+ name = lines[3].substring(" <name>".length).trim();
+ name = name.substring(0, name.indexOf("<"));
+ description = lines[4].substring(" <description>".length).trim();
+ description = description.substring(0, description.indexOf("<"));
+ if (lines[5].indexOf("grade") >= 0) {
+ grade = lines[5].substring(" <grade>".length).trim();
+ grade = grade.substring(0, grade.indexOf("<"));
+ }
+
+ disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
+
+ insertSql = "insert into " + tableName + " (report_name, report_descrip, " +
+ "report_source, report_loaddate, report_grade) select " +
+ "'" + name + "'," +
+ "$$" + description + "$$," +
+ "$$" + content + "$$," +
+ "now(), " + grade +
+ " where not exists (select c.report_id from " + tableName + " c " +
+ "where report_name = '" + name +
+ "' and report_grade = " + grade + ");";
+
+ updateSql = "update " + tableName + " set " +
+ " report_descrip = $$" + description +
+ "$$, report_source = $$" + content +
+ "$$, report_loaddate = now() " +
+ "where report_name = '" + name +
+ "' and report_grade = " + grade + ";";
+
+ enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
+
+ return disableSql + insertSql + updateSql + enableSql;
+ };
+
+ var convertFromScript = function (content, filename, defaultSchema) {
+ var name = path.basename(filename, '.js'),
+ tableName = defaultSchema ? defaultSchema + ".pkgscript" : "unknown",
+ notes = "", //"xtMfg package",
+ disableSql,
+ insertSql,
+ updateSql,
+ enableSql;
+
+ disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
+
+ insertSql = "insert into " + tableName + " (script_name, script_order, script_enabled, " +
+ "script_source, script_notes) select " +
+ "'" + name + "', 0, TRUE, " +
+ "$$" + content + "$$," +
+ "'" + notes + "'" +
+ " where not exists (select c.script_id from " + tableName + " c " +
+ "where script_name = '" + name + "');";
+
+ updateSql = "update " + tableName + " set " +
+ "script_name = '" + name + "', script_order = 0, script_enabled = TRUE, " +
+ "script_source = $$" + content +
+ "$$, script_notes = '" + notes + "' " +
+ "where script_name = '" + name + "';";
+
+ enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
+
+ return disableSql + insertSql + updateSql + enableSql;
+ };
+
+ var convertFromUiform = function (content, filename, defaultSchema) {
+ var name = path.basename(filename, '.ui'),
+ tableName = defaultSchema ? defaultSchema + ".pkguiform" : "unknown",
+ notes = "", //"xtMfg package",
+ disableSql,
+ insertSql,
+ updateSql,
+ enableSql;
+
+ disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
+
+ insertSql = "insert into " + tableName + " (uiform_name, uiform_order, uiform_enabled, " +
+ "uiform_source, uiform_notes) select " +
+ "'" + name + "', 0, TRUE, " +
+ "$$" + content + "$$," +
+ "'" + notes + "' " +
+ " where not exists (select c.uiform_id from " + tableName + " c " +
+ "where uiform_name = '" + name + "');";
+
+ updateSql = "update " + tableName + " set uiform_name = '" +
+ name + "', uiform_order = 0, uiform_enabled = TRUE, " +
+ "uiform_source = $$" + content + "$$, uiform_notes = '" + notes + "' " +
+ "where uiform_name = '" + name + "';";
+
+ enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
+
+ return disableSql + insertSql + updateSql + enableSql;
+ };
+
+ exports.conversionMap = {
+ mql: convertFromMetasql,
+ xml: convertFromReport,
+ js: convertFromScript,
+ ui: convertFromUiform,
+ sql: function (content) {
+ // no op
+ return content;
+ }
+ };
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var path = require('path');
+
+ exports.extensions = [
+ path.join(__dirname, '../../../foundation-database'),
+ path.join(__dirname, '../../../lib/orm'),
+ path.join(__dirname, '../../../enyo-client'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/crm'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/project'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/sales'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/billing'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/purchasing'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/oauth2')
+ ];
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var async = require("async"),
+ proc = require('child_process'),
+ path = require('path'),
+ os = require('os'),
+ winston = require('winston'),
+ dataSource = require('../../../node-datasource/lib/ext/datasource').dataSource,
+ inspectDatabaseExtensions = require("./inspect_database").inspectDatabaseExtensions;
+
+ //
+ // Wipe out the database
+ // and load it from scratch using pg_restore something.backup unless
+ // we're building from source.
+ //
+ var initDatabase = function (spec, creds, callback) {
+ var databaseName = spec.database,
+ credsClone = JSON.parse(JSON.stringify(creds)),
+ dropDatabase = function (done) {
+ winston.info("Dropping database " + databaseName);
+ // the calls to drop and create the database need to be run against the database "postgres"
+ credsClone.database = "postgres";
+ dataSource.query("drop database if exists " + databaseName + ";", credsClone, done);
+ },
+ createDatabase = function (done) {
+ winston.info("Creating database " + databaseName);
+ dataSource.query("create database " + databaseName + " template template1;", credsClone, done);
+ },
+ buildSchema = function (done) {
+ var schemaPath = path.join(path.dirname(spec.source), "440_schema.sql");
+ winston.info("Building schema for database " + databaseName);
+
+ 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);
+ 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) {
+ 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);
+ }
+ done(null, res);
+ });
+ },
+ finish = function (err, results) {
+ if (err) {
+ winston.error("init database error", err.message, err.stack, err);
+ }
+ callback(err, results);
+ };
+
+ if (spec.source) {
+ async.series([
+ dropDatabase,
+ createDatabase,
+ buildSchema,
+ populateData
+ ], finish);
+ } else {
+ async.series([
+ dropDatabase,
+ createDatabase,
+ restoreBackup,
+ function (done) {
+ credsClone.database = databaseName;
+ inspectDatabaseExtensions(credsClone, function (err, paths) {
+ // in the case of a build-from-backup, we ignore any user desires and dictate the extensions
+ spec.extensions = paths;
+ done();
+ });
+ }
+ ], finish);
+ }
+ };
+
+ exports.initDatabase = initDatabase;
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var path = require('path'),
+ dataSource = require('../../../node-datasource/lib/ext/datasource').dataSource,
+ defaultExtensions = require("./default_extensions").extensions;
+
+ var pathFromExtension = function (name, location) {
+ if (location === '/core-extensions') {
+ return path.join(__dirname, "../../../enyo-client/extensions/source/", name);
+ } else if (location === '/xtuple-extensions') {
+ return path.join(__dirname, "../../../../xtuple-extensions/source", name);
+ } else if (location === '/private-extensions') {
+ return path.join(__dirname, "../../../../private-extensions/source", name);
+ } else if (location === 'npm') {
+ return path.join(__dirname, "../../../node_modules", name);
+ }
+ };
+
+ //
+ // Looks in a database to see which extensions are registered, and
+ // tacks onto that list the core directories.
+ //
+ var inspectMobilizedDatabase = function (creds, done) {
+ var extSql = "SELECT * FROM xt.ext ORDER BY ext_load_order";
+ dataSource.query(extSql, creds, function (err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ var paths = _.map(_.compact(res.rows), function (row) {
+ return pathFromExtension(row.ext_name, row.ext_location);
+ });
+
+ paths.unshift(path.join(__dirname, "../../../enyo-client")); // core path
+ paths.unshift(path.join(__dirname, "../../../lib/orm")); // lib path
+ paths.unshift(path.join(__dirname, "../../../foundation-database")); // foundation path
+ done(null, _.compact(paths));
+ });
+ };
+
+ var inspectUnmobilizedDatabase = function (creds, done) {
+ var extSql = "select * from public.pkghead where pkghead_name in ('xtmfg', 'xwd');",
+ editionMap = {
+ xtmfg: ["inventory", "manufacturing"],
+ xwd: ["inventory", "distribution"]
+ };
+ dataSource.query(extSql, creds, function (err, res) {
+ if (err) {
+ return done(err);
+ }
+ var extensions = _.unique(_.flatten(_.map(res.rows, function (row) {
+ return _.map(editionMap[row.pkghead_name], function (ext) {
+ return path.join(__dirname, "../../../../private-extensions/source", ext);
+ });
+ })));
+ done(err, defaultExtensions.concat(extensions));
+ });
+ };
+
+ var inspectDatabaseExtensions = function (creds, done) {
+ var isMobilizedSql = "select * from information_schema.tables where table_schema = 'xt' and table_name = 'ext';";
+
+ dataSource.query(isMobilizedSql, creds, function (err, res) {
+ if (res.rowCount === 0) {
+ inspectUnmobilizedDatabase(creds, done);
+ } else {
+ inspectMobilizedDatabase(creds, done);
+ }
+ });
+ };
+
+ exports.inspectDatabaseExtensions = inspectDatabaseExtensions;
+
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var _ = require('underscore'),
+ async = require('async'),
+ exec = require('child_process').exec,
+ fs = require('fs'),
+ path = require('path'),
+ conversionMap = require("./convert_specialized").conversionMap,
+ dataSource = require('../../../node-datasource/lib/ext/datasource').dataSource,
+ inspectDatabaseExtensions = require("./inspect_database").inspectDatabaseExtensions;
+
+ // register extension and dependencies
+ var getRegistrationSql = function (options, extensionLocation) {
+ var registerSql = 'do $$ plv8.elog(NOTICE, "About to register extension ' +
+ options.name + '"); $$ language plv8;\n';
+
+ registerSql = registerSql + "select xt.register_extension('%@', '%@', '%@', '', %@);\n"
+ .f(options.name, options.description || options.comment, extensionLocation, options.loadOrder || 9999);
+
+ registerSql = registerSql + "select xt.grant_role_ext('ADMIN', '%@');\n"
+ .f(options.name);
+
+ // TODO: infer dependencies from package.json using peerDependencies
+ var dependencies = options.dependencies || [];
+ _.each(dependencies, function (dependency) {
+ var dependencySql = "select xt.register_extension_dependency('%@', '%@');\n"
+ .f(options.name, dependency),
+ grantDependToAdmin = "select xt.grant_role_ext('ADMIN', '%@');\n"
+ .f(dependency);
+
+ registerSql = registerSql + dependencySql + grantDependToAdmin;
+ });
+ return registerSql;
+ };
+
+ var composeExtensionSql = function (scriptSql, packageFile, options, callback) {
+ // each String of the scriptContents is the concatenated SQL for the script.
+ // join these all together into a single string for the whole extension.
+ var extensionSql = _.reduce(scriptSql, function (memo, script) {
+ return memo + script;
+ }, "");
+
+ if (options.registerExtension) {
+ extensionSql = getRegistrationSql(packageFile, options.extensionLocation) +
+ extensionSql;
+ }
+ if (options.runJsInit) {
+ // unless it it hasn't yet been defined (ie. lib/orm),
+ // running xt.js_init() is probably a good idea.
+ extensionSql = "select xt.js_init();" + extensionSql;
+ }
+
+ if (options.wipeViews) {
+ // If we want to pre-emptively wipe out the views, the best place to do it
+ // is at the start of the core application code
+ fs.readFile(path.join(__dirname, "../../../enyo-client/database/source/delete_system_orms.sql"),
+ function (err, wipeSql) {
+ if (err) {
+ callback(err);
+ return;
+ }
+ extensionSql = wipeSql + extensionSql;
+ callback(null, extensionSql);
+ });
+ } else {
+ callback(null, extensionSql);
+ }
+ };
+
+ var explodeManifest = function (options, manifestCallback) {
+ var manifestFilename = options.manifestFilename;
+ var packageJson;
+ var dbSourceRoot = path.dirname(manifestFilename);
+
+ if (options.extensionPath && fs.existsSync(path.resolve(options.extensionPath, "package.json"))) {
+ packageJson = require(path.resolve(options.extensionPath, "package.json"));
+ }
+ //
+ // Step 2:
+ // Read the manifest files.
+ //
+
+ if (!fs.existsSync(manifestFilename) && packageJson) {
+ console.log("No manifest file " + manifestFilename + ". There is probably no db-side code in the extension.");
+ composeExtensionSql([], packageJson, options, manifestCallback);
+ return;
+
+ } else if (!fs.existsSync(manifestFilename)) {
+ // error condition: no manifest file
+ manifestCallback("Cannot find manifest " + manifestFilename);
+ return;
+ }
+ fs.readFile(manifestFilename, "utf8", function (err, manifestString) {
+ var manifest,
+ databaseScripts,
+ extraManifestPath,
+ defaultSchema,
+ extraManifest,
+ extraManifestScripts,
+ alterPaths = dbSourceRoot.indexOf("foundation-database") < 0;
+
+ try {
+ manifest = JSON.parse(manifestString);
+ databaseScripts = manifest.databaseScripts;
+ defaultSchema = manifest.defaultSchema;
+
+ } catch (error) {
+ // error condition: manifest file is not properly formatted
+ manifestCallback("Manifest is not valid JSON" + manifestFilename);
+ return;
+ }
+
+ //
+ // Step 2b:
+ //
+
+ // supported use cases:
+
+ // 1. add mobilized inventory to quickbooks
+ // need the frozen_manifest, the foundation/manifest, and the mobile manifest
+ // -e ../private-extensions/source/inventory -f
+ // useFrozenScripts, useFoundationScripts
+
+ // 2. add mobilized inventory to masterref (foundation inventory is already there)
+ // need the the foundation/manifest and the mobile manifest
+ // -e ../private-extensions/source/inventory
+ // useFoundationScripts
+
+ // 3. add unmobilized inventory to quickbooks
+ // need the frozen_manifest and the foundation/manifest
+ // -e ../private-extensions/source/inventory/foundation-database -f
+ // useFrozenScripts (useFoundationScripts already taken care of by -e path)
+
+ // 4. upgrade unmobilized inventory
+ // not sure if this is necessary, but it would look like
+ // -e ../private-extensions/source/inventory/foundation-database
+
+ if (options.useFoundationScripts) {
+ extraManifest = JSON.parse(fs.readFileSync(path.join(dbSourceRoot, "../../foundation-database/manifest.js")));
+ defaultSchema = defaultSchema || extraManifest.defaultSchema;
+ extraManifestScripts = extraManifest.databaseScripts;
+ extraManifestScripts = _.map(extraManifestScripts, function (path) {
+ return "../../foundation-database/" + path;
+ });
+ databaseScripts.unshift(extraManifestScripts);
+ databaseScripts = _.flatten(databaseScripts);
+ }
+ if (options.useFrozenScripts) {
+ // Frozen files are not idempotent and should only be run upon first registration
+ extraManifestPath = alterPaths ?
+ path.join(dbSourceRoot, "../../foundation-database/frozen_manifest.js") :
+ path.join(dbSourceRoot, "frozen_manifest.js");
+
+ extraManifest = JSON.parse(fs.readFileSync(extraManifestPath));
+ defaultSchema = defaultSchema || extraManifest.defaultSchema;
+ extraManifestScripts = extraManifest.databaseScripts;
+ if (alterPaths) {
+ extraManifestScripts = _.map(extraManifestScripts, function (path) {
+ return "../../foundation-database/" + path;
+ });
+ }
+ databaseScripts.unshift(extraManifestScripts);
+ databaseScripts = _.flatten(databaseScripts);
+ }
+
+ //
+ // Step 3:
+ // Concatenate together all the files referenced in the manifest.
+ //
+ var getScriptSql = function (filename, scriptCallback) {
+ var fullFilename = path.join(dbSourceRoot, filename);
+ if (!fs.existsSync(fullFilename)) {
+ // error condition: script referenced in manifest.js isn't there
+ scriptCallback(path.join(dbSourceRoot, filename) + " does not exist");
+ return;
+ }
+ fs.readFile(fullFilename, "utf8", function (err, scriptContents) {
+ // error condition: can't read script
+ if (err) {
+ scriptCallback(err);
+ return;
+ }
+ var beforeNoticeSql = "do $$ BEGIN RAISE NOTICE 'Loading file " + path.basename(fullFilename) +
+ "'; END $$ language plpgsql;\n",
+ extname = path.extname(fullFilename).substring(1);
+
+ // convert special files: metasql, uiforms, reports, uijs
+ scriptContents = conversionMap[extname](scriptContents, fullFilename, defaultSchema);
+
+ //
+ // Incorrectly-ended sql files (i.e. no semicolon) make for unhelpful error messages
+ // when we concatenate 100's of them together. Guard against these.
+ //
+ scriptContents = scriptContents.trim();
+ if (scriptContents.charAt(scriptContents.length - 1) !== ';') {
+ // error condition: script is improperly formatted
+ scriptCallback("Error: " + fullFilename + " contents do not end in a semicolon.");
+ }
+
+ scriptCallback(null, '\n' + scriptContents);
+ });
+ };
+ async.mapSeries(databaseScripts || [], getScriptSql, function (err, scriptSql) {
+ var registerSql,
+ dependencies;
+
+ if (err) {
+ manifestCallback(err);
+ return;
+ }
+
+ composeExtensionSql(scriptSql, packageJson || manifest, options, manifestCallback);
+
+ });
+ //
+ // End script installation code
+ //
+ });
+ };
+
+ exports.explodeManifest = explodeManifest;
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var exec = require('child_process').exec,
+ fs = require('fs'),
+ path = require('path'),
+ winston = require('winston');
+
+ var sendToDatabase = function (query, credsClone, options, callback) {
+ var filename = path.join(__dirname, "../../output/build_" + credsClone.database + ".sql");
+ if (!fs.existsSync(path.join(__dirname, "../../output"))) {
+ fs.mkdirSync(path.join(__dirname, "../../output"));
+ }
+ fs.writeFile(filename, query, function (err) {
+ if (err) {
+ winston.error("Cannot write query to file");
+ callback(err);
+ return;
+ }
+ var psqlCommand = 'psql -d ' + credsClone.database +
+ ' -U ' + credsClone.username +
+ ' -h ' + credsClone.hostname +
+ ' -p ' + credsClone.port +
+ ' -f ' + filename +
+ ' --single-transaction';
+
+ /**
+ * http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
+ * "maxBuffer specifies the largest amount of data allowed on stdout or
+ * stderr - if this value is exceeded then the child process is killed."
+ */
+ exec(psqlCommand, {maxBuffer: 40000 * 1024 /* 200x default */}, function (err, stdout, stderr) {
+ if (err) {
+ winston.error("Cannot install file ", filename);
+ callback(err);
+ return;
+ }
+ if (options.keepSql) {
+ // do not delete the temp query file
+ winston.info("SQL file kept as ", filename);
+ callback();
+ } else {
+ fs.unlink(filename, function (err) {
+ if (err) {
+ winston.error("Cannot delete written query file");
+ callback(err);
+ }
+ callback();
+ });
+ }
+ });
+ });
+ };
+ exports.sendToDatabase = sendToDatabase;
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var async = require("async"),
+ path = require('path'),
+ winston = require('winston'),
+ dataSource = require('../../../node-datasource/lib/ext/datasource').dataSource;
+
+ //
+ // Unregister the extension
+ //
+ var unregister = function (specs, creds, masterCallback) {
+ var extension = path.basename(specs[0].extensions[0]),
+ unregisterSql = ["delete from xt.usrext where usrext_id in " +
+ "(select usrext_id from xt.usrext inner join xt.ext on usrext_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.grpext where grpext_id in " +
+ "(select grpext_id from xt.grpext inner join xt.ext on grpext_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.clientcode where clientcode_id in " +
+ "(select clientcode_id from xt.clientcode inner join xt.ext on clientcode_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.dict where dict_id in " +
+ "(select dict_id from xt.dict inner join xt.ext on dict_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.extdep where extdep_id in " +
+ "(select extdep_id from xt.extdep inner join xt.ext " +
+ "on extdep_from_ext_id = ext_id or extdep_to_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.ext where ext_name = $1;"];
+
+ if (extension.charAt(extension.length - 1) === "/") {
+ // remove trailing slash if present
+ extension = extension.substring(0, extension.length - 1);
+ }
+ winston.info("Unregistering extension:", extension);
+ var unregisterEach = function (spec, callback) {
+ var options = JSON.parse(JSON.stringify(creds));
+ options.database = spec.database;
+ options.parameters = [extension];
+ var queryEach = function (sql, sqlCallback) {
+ dataSource.query(sql, options, sqlCallback);
+ };
+ async.eachSeries(unregisterSql, queryEach, callback);
+ };
+ async.each(specs, unregisterEach, masterCallback);
+ };
+
+ exports.unregister = unregister;
+}());
+
<package id = "distribution-install-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
- <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+ <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>
<package id = "distribution-upgrade-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
- <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+ <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>
<package id = "postbooks-upgrade-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
- <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+ <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>
<package id = "manufacturing-install-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
- <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+ <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>
<package id = "manufacturing-upgrade-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
-<query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+<query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>
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;
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);
});
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()) {
});
afterEach(function (done) {
- this.timeout(10 * 1000);
+ this.timeout(30 * 1000);
// restore permissions
_.extend(XT.session.privileges.attributes, originalPrivileges);
});
};
- 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; }
// 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});
});
// 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);
});
//
_.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);
});
// 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);
});
});
//
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);
});
});
// 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);
});
}
//
_.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);
});
});
_.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?");
});
});
/*
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(10 * 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);
});
};
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 = {};
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');
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)
(function () {
"use strict";
+ var assert = require("chai").assert;
+
/**
@class
@alias Country
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;
/*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
+}());