Merge pull request #1692 from garyhgohoos/24154
authorGil Moskowitz <gmoskowitz@xtuple.com>
Thu, 31 Jul 2014 16:19:15 +0000 (12:19 -0400)
committerGil Moskowitz <gmoskowitz@xtuple.com>
Thu, 31 Jul 2014 16:19:15 +0000 (12:19 -0400)
Issue #24154:remove redundant create supply order logic handled by trigg...

28 files changed:
README.md
RELEASE.md
foundation-database/public/functions/calcinvoiceamt.sql
foundation-database/public/functions/calcsalesorderamt.sql
foundation-database/public/tables/metasql/bankrec-clearedbalance.mql
foundation-database/public/tables/metasql/bankrecHistory-reconciled.mql
foundation-database/public/tables/metasql/bookings-detail.mql
foundation-database/public/tables/metasql/briefSalesHistory-detail.mql
foundation-database/public/tables/metasql/invoices-detail.mql
foundation-database/public/tables/metasql/itemPricingSchedule-detail.mql
foundation-database/public/tables/metasql/opensalesorders-detail.mql
foundation-database/public/tables/metasql/salesHistory-detail.mql
foundation-database/public/tables/report/BankrecHistory.xml
foundation-database/public/views/saleshistory.sql
lib/backbone-x/source/model_mixin.js
lib/enyo-x/source/less/dashboard.less
lib/enyo-x/source/stylesheets/screen.css
lib/enyo-x/source/views/module_container.js
lib/orm/source/xt/javascript/discovery.sql
lib/orm/source/xt/javascript/schema.sql
scripts/lib/build_all.js
scripts/lib/build_database.js
scripts/lib/build_database_util.js
scripts/xml/distribution_install.xml
scripts/xml/distribution_package.xml
scripts/xml/postbooks_package.xml
scripts/xml/xtmfg_install.xml
scripts/xml/xtmfg_package.xml

index 6d16979..cce4569 100644 (file)
--- a/README.md
+++ b/README.md
@@ -46,7 +46,8 @@ In the month of August, we will be running haxTuple 2014. As in previous incarna
 we will open up our bug-shooting derby for the Qt client to our community, with prizes 
 for the most effective bugsquashers! In this year's event, we will also introduce our 
 new technologies by opening up our webapp for haxxing. Those who write the best 
-JavaScript extensions or REST clients will get prizes. More details to follow.
+JavaScript extensions or REST clients will get prizes. More details 
+[here](https://github.com/xtuple/xtuple/wiki/haxTuple-2014).
 
 Also, don't miss the xTuple event of the year! 
 [xTupleCon 2014](http://www.xtuple.com/xtuple-conference-2014)
@@ -63,8 +64,8 @@ The best way to start coding on our stack is to use our
 View the [Release Notes](RELEASE.md) to see a change log.
 
 ### Additional Resources
-
-  * [Setting up a non-development demo environment](https://github.com/xtuple/xtuple/wiki/How-to-set-up-xTuple)
   * [Building an Extension Tutorial](https://github.com/xtuple/xtuple-extensions/blob/master/docs/TUTORIAL.md)
-  * [API documentation](http://xtuple.com/jsdoc)
   * [Developer Wiki](https://github.com/xtuple/xtuple/wiki)
+  * xTuple U [Tutorial Videos](https://github.com/xtuple/xtuple/wiki/Tutorial-Videos)
+  * [API documentation](http://xtuple.github.io/api/current)
+  * [Setting up a non-development demo environment](https://github.com/xtuple/xtuple/wiki/How-to-set-up-xTuple)
index be4f8fc..e7039d6 100644 (file)
@@ -1,3 +1,138 @@
+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)
 ==================
 
index fb79c3f..a60452d 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
   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)
index 0f4def9..cf11cab 100644 (file)
@@ -41,7 +41,7 @@ BEGIN
     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)
index d251cd2..c643759 100644 (file)
@@ -16,6 +16,7 @@ SELECT (COALESCE(SUM(amount),0.0) + <? value("begBal") ?>) AS cleared_amount,
             AND (bankrecitem_source_id=gltrans_id)
             AND (bankrecitem_bankrec_id=<? value("bankrecid") ?>)
             AND (bankrecitem_cleared)
+            AND (NOT gltrans_deleted)
             AND (NOT gltrans_rec)
             AND (bankaccnt_id=<? value("bankaccntid") ?>) ) 
           UNION ALL
index e6db42d..7fd754b 100644 (file)
@@ -36,7 +36,8 @@ SELECT gltrans_id, gltrans_date, formatDate(gltrans_date) AS f_date,
     JOIN bankaccnt ON (bankaccnt_id=bankrec_bankaccnt_id)
  WHERE ((bankrecitem_bankrec_id=<? value("bankrec_id") ?>)
    AND (bankrecitem_source='GL')
-   AND (bankrecitem_source_id=gltrans_id) ) 
+   AND (bankrecitem_source_id=gltrans_id)
+   AND (NOT gltrans_deleted) ) 
 
 UNION
 
index 6214403..28a6f08 100644 (file)
@@ -29,6 +29,21 @@ SELECT   coitem_id AS id, coitem_cohead_id AS altId,
                      (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,
+         (round((coitem_qtyord * coitem_qty_invuomratio) *
+                     (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2) -
+          round((coitem_qtyord * coitem_qty_invuomratio) *
+                     (coitem_unitcost / coitem_price_invuomratio), 2)) AS margin,
+         CASE WHEN (coitem_price > 0.0) THEN
+           (round((coitem_qtyord * coitem_qty_invuomratio) *
+                       (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2) -
+            round((coitem_qtyord * coitem_qty_invuomratio) *
+                       (coitem_unitcost / coitem_price_invuomratio), 2)) /
+            round((coitem_qtyord * coitem_qty_invuomratio) *
+                       (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2)
+              ELSE 0.0
+         END AS marginpercent,
          curr_abbr AS currAbbr,
 -- TODO - not needed, remove? (very slow)
 --         CASE WHEN (qtyAvailable(itemsite_id, coitem_scheddate) < 0.0) THEN 'error'
@@ -43,7 +58,11 @@ SELECT   coitem_id AS id, coitem_cohead_id AS altId,
        '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,
index 8dc7a25..b79e353 100644 (file)
@@ -7,15 +7,28 @@
 SELECT
        COALESCE(cohead_id,-1) AS cohead_id, cust_id, cohist_ponumber,
        cust_custtype_id, custtype_code,
-       cohist_cust_id, SUM(extcost) AS extcost,
+       cohist_cust_id, cohist_ordernumber,
+       cust_number, cust_name, currAbbr,
+       CASE WHEN (cohist_invcnumber='-1') THEN  <? value("credit") ?>
+            ELSE cohist_invcnumber
+       END AS invoicenumber,
+       cohist_orderdate, cohist_invcdate,
+       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,
+       '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
+       0 AS margin_xttotalrole
 FROM saleshistory
   LEFT OUTER JOIN cohead ON (cohead_number=cohist_ordernumber)
 WHERE ((cohist_invcdate BETWEEN <? value("startDate") ?> AND  <? value("endDate") ?>)
@@ -60,7 +73,8 @@ WHERE ((cohist_invcdate BETWEEN <? value("startDate") ?> AND  <? value("endDate"
    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,
-         invoicenumber,cohist_orderdate, cohist_invcdate
+GROUP BY cohead_id, cust_id, cust_number, cust_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;
index 67ee698..20b3648 100644 (file)
@@ -29,11 +29,16 @@ SELECT invchead_id, cust_id,
          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
index 0ed0c04..ba1ab0c 100644 (file)
@@ -15,7 +15,9 @@ SELECT ipsitem_id AS id, 1 AS altid,
        price.uom_name AS priceuom,
        ((COALESCE(ipsitem_discntprcnt, 0.0) * 100) + ipsitem_price) AS price,
        (COALESCE(ipsitem_fixedamtdiscount, 0.0) + 0.00) AS fixedAmt,
-       noNeg(CASE WHEN (ipsitem_type='N') THEN
+       noNeg(CASE WHEN (ipsitem_item_id IS NULL) THEN
+                   NULL
+                  WHEN (ipsitem_type='N') THEN
                    ipsitem_price
                   WHEN (ipsitem_type='D') THEN
                    (item_listprice - (item_listprice * COALESCE(ipsitem_discntprcnt, 0.0)) - COALESCE(ipsitem_fixedamtdiscount, 0.0))
index 81385aa..bb58084 100644 (file)
@@ -20,12 +20,17 @@ SELECT DISTINCT
 <? 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)
index 50da06f..c427dea 100644 (file)
@@ -4,58 +4,29 @@
 --        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.*,
+SELECT *,
        CASE WHEN (cohist_invcnumber='-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_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,
+       formatPercent(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)
-<? 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 ?>
+  FROM saleshistory
 <? if exists("cohead_id") ?>
               JOIN cohead ON (cohead_number=cohist_ordernumber)
 <? endif ?>
@@ -63,6 +34,8 @@ WHERE ( (true)
 <? if exists("includeMisc") ?>
   AND  (COALESCE(cohist_misc_type, '') <> 'F')
   AND  (COALESCE(cohist_misc_type, '') <> 'T')
+<? else ?>
+  AND  (warehous_id IS NOT NULL)
 <? endif ?>
 <? if exists("startDate") ?>
   AND  (cohist_invcdate >= <? value("startDate") ?>)
index 3c2b34a..8ffe63e 100644 (file)
@@ -39,8 +39,8 @@
   <name>Subtotal</name>
   <sql>SELECT 
    formatMoney(COALESCE(MAX(selrec.bankrec_endbal) +
---   SUM(currtolocal(bankaccnt_curr_id,gltrans_amount,gltrans_date) * -1),0)) AS amount
-   SUM(currtolocal(bankaccnt_curr_id,gltrans_amount,gltrans_date)),0)) AS amount
+   SUM(currtolocal(bankaccnt_curr_id,gltrans_amount,gltrans_date) * -1),0)) AS amount
+--   SUM(currtolocal(bankaccnt_curr_id,gltrans_amount,gltrans_date)),0)) AS amount
  FROM gltrans
    JOIN bankaccnt ON (bankaccnt_accnt_id = gltrans_accnt_id)
    JOIN bankrec selrec ON ((selrec.bankrec_bankaccnt_id = bankaccnt_id)
@@ -55,8 +55,8 @@
   <name>ActualAmount</name>
   <sql>SELECT 
    formatMoney(COALESCE(MAX(selrec.bankrec_endbal) +
---   SUM(currtolocal(bankaccnt_curr_id,gltrans_amount,gltrans_date) * -1),0)) AS amount
-   SUM(currtolocal(bankaccnt_curr_id,gltrans_amount,gltrans_date)),0)) AS amount
+   SUM(currtolocal(bankaccnt_curr_id,gltrans_amount,gltrans_date) * -1),0)) AS amount
+--   SUM(currtolocal(bankaccnt_curr_id,gltrans_amount,gltrans_date)),0)) AS amount
  FROM gltrans
    JOIN bankaccnt ON (bankaccnt_accnt_id = gltrans_accnt_id)
    JOIN bankrec selrec ON ((selrec.bankrec_bankaccnt_id = bankaccnt_id)
     <height>136.499</height>
     <label>
      <rect>
-      <x>454</x>
-      <y>41.4985</y>
+      <x>450</x>
+      <y>43</y>
       <width>162</width>
       <height>15</height>
      </rect>
      </font>
      <right/>
      <vcenter/>
-     <string>Add: Checks in Circulation:</string>
+     <string>Checks in Circulation:</string>
     </label>
     <label>
      <rect>
     </label>
     <label>
      <rect>
-      <x>453</x>
-      <y>73.5</y>
+      <x>450</x>
+      <y>73</y>
       <width>163</width>
       <height>15</height>
      </rect>
      </font>
      <right/>
      <vcenter/>
-     <string>Deduct: Deposits in Circulation:</string>
+     <string>Deposits in Circulation:</string>
     </label>
     <label>
      <rect>
-      <x>396</x>
-      <y>105</y>
+      <x>395</x>
+      <y>103</y>
       <width>219</width>
       <height>15</height>
      </rect>
     </label>
     <label>
      <rect>
-      <x>454</x>
-      <y>25.5</y>
+      <x>450</x>
+      <y>28</y>
       <width>162</width>
       <height>15</height>
      </rect>
     </label>
     <field>
      <rect>
-      <x>642</x>
-      <y>25.4985</y>
+      <x>640</x>
+      <y>28</y>
       <width>100</width>
       <height>15</height>
      </rect>
     </field>
     <field>
      <rect>
-      <x>642</x>
-      <y>41.5</y>
+      <x>640</x>
+      <y>43</y>
       <width>100</width>
       <height>15</height>
      </rect>
     </field>
     <label>
      <rect>
-      <x>559</x>
-      <y>57.4985</y>
+      <x>555</x>
+      <y>58</y>
       <width>56</width>
       <height>15</height>
      </rect>
     </label>
     <field>
      <rect>
-      <x>641</x>
-      <y>57.5</y>
+      <x>640</x>
+      <y>58</y>
       <width>100</width>
       <height>15</height>
      </rect>
     </field>
     <field>
      <rect>
-      <x>642</x>
-      <y>73.5</y>
+      <x>640</x>
+      <y>73</y>
       <width>100</width>
       <height>15</height>
      </rect>
     </field>
     <field>
      <rect>
-      <x>641</x>
-      <y>89.5</y>
+      <x>640</x>
+      <y>88</y>
       <width>100</width>
       <height>15</height>
      </rect>
     </field>
     <field>
      <rect>
-      <x>641</x>
-      <y>105</y>
+      <x>640</x>
+      <y>103</y>
       <width>100</width>
       <height>15</height>
      </rect>
     </field>
     <label>
      <rect>
-      <x>439</x>
-      <y>89.499</y>
+      <x>435</x>
+      <y>88</y>
       <width>177</width>
       <height>15</height>
      </rect>
      </font>
      <right/>
      <vcenter/>
-     <string>Add: Adjustments in Circulation:</string>
+     <string>Adjustments in Circulation:</string>
     </label>
    </foot>
   </group>
index 7db4ed2..d648700 100644 (file)
@@ -1,21 +1,18 @@
 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 *,
+       COALESCE(item_number, cohist_misc_descrip) AS itemnumber,
+       (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
        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,
@@ -27,22 +24,26 @@ SELECT cohist.*,
        '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 *,
+       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)
-            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 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);
+            LEFT OUTER JOIN shipzone ON (shipzone_id=shipto_shipzone_id)
+            LEFT OUTER JOIN saletype ON (saletype_id=cohist_saletype_id)
+     ) AS data;
 
 REVOKE ALL ON TABLE saleshistory FROM PUBLIC;
 GRANT  ALL ON TABLE saleshistory TO GROUP xtrole;
index b877b73..dd91679 100644 (file)
@@ -5,6 +5,8 @@
 (function () {
   'use strict';
 
+  Object.observe = undefined;
+
   /**
     Abstract check for attribute level privilege access.
 
index dd2a6b2..502edbd 100644 (file)
@@ -90,6 +90,7 @@
     .icon-filter {
        color: @black;
        position: absolute;
+       top: 0;
        right: 35px;
     }
   }
   .chart-filterDrawer {
     top: 0px;
   }
+  
+  .map-cluster {
+    width: 40px;
+    height: 40px;
+    background-color: greenyellow;
+    text-align: center;
+    font-size: 24px;
+  }
 
   /*  The chart-filters may not be need as we are using the class xv-pullout
       for styles.  Delete when finished hacking the filter styles.
index 0edfcd6..62aa1aa 100755 (executable)
   border: none;
 }
 /**
- * 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;
+  Styles relating to Lists
+*/
+.xv-list-header {
+  background-color: #d8d8d8;
+  color: #fdfdfd;
+  font-size: .6em;
   font-weight: bold;
-  cursor: pointer;
+  text-transform: uppercase;
+  padding-top: 4px;
+  padding-bottom: 4px;
+  border-bottom: 1px solid #aaaaaa;
 }
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-name {
-  font-weight: bold;
+.xv-list-header .xv-list-column.last {
+  border-right: none;
 }
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-number {
-  text-align: right;
+.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.xm-attributetype-money {
+/* 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-attributetype-date {
+.xv-list-column.name-column {
+  width: 200px;
+}
+.xv-list-column.right-column {
+  width: 100px;
   text-align: right;
 }
-.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr {
-  color: white;
+.xv-list-column.short {
+  width: 100px;
 }
-.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr.xm-attribute-id {
-  color: #ff6529;
+.xv-list-column.small {
+  width: 125px;
 }
-/**
-  Styles related to pickers, combo boxes, and relation widgets
-*/
-.onyx-picker-decorator .onyx-button {
-  padding: 12px 8px 12px 8px;
+.xv-list-column.medium {
   width: 150px;
 }
-.onyx-picker .onyx-menu-item {
-  text-align: left;
-  text-overflow: ellipsis;
+.xv-list-column.first {
+  width: 300px;
 }
-.picker-icon {
-  position: absolute;
-  right: 0;
-  margin: 0 10px 0 2px;
-  color: #070707;
+.xv-list-column.second {
+  width: 200px;
 }
-.xv-picker-button {
-  text-align: left;
+.xv-list-column.third {
+  width: 100px;
 }
-.xv-picker-button .picker-content {
-  max-width: 100px;
-  overflow: hidden;
+.xv-list-column.money,
+.xv-list-column.quantity {
+  width: 75px;
+  text-align: right;
 }
-.xv-picker-button.disabled {
-  color: #777777;
+.xv-list-column.descr {
+  width: 200px;
 }
-.xv-picker-label {
+.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;
-  padding: 20px 8px 8px 8px;
-  text-align: right;
-  width: 130px;
 }
-.xv-picker-label.disabled {
-  color: #777777;
+.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr {
+  background: transparent;
 }
-.xv-combobox-note {
-  padding: 14px 3px 8px 3px;
-  text-align: left;
+.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr.placeholder {
+  color: #d8d8d8;
 }
-/*
-  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 .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-grid-box.small-panel {
-  width: 600px;
+.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-grid-box.medium-panel {
-  width: 700px;
+.xv-list .xv-list-item.item-selected .xv-list-attr {
+  color: #fdfdfd;
 }
-.xv-grid-box.large-panel {
-  width: 800px;
+.xv-list .xv-list-item.item-selected .xv-list-attr.placeholder {
+  font-style: italic;
+  color: #99ccff;
 }
-.xv-grid-box .enyo-list-page > *:first-child .xv-grid-row {
-  border-top: 0;
+.xv-list .xv-list-item.item-selected .xv-list-attr.hyperlink {
+  color: #ff6529;
 }
-.xv-grid-box .xv-above-grid-list {
-  border: 0;
+.xv-list .xv-list-item.item-selected .xv-list-attr.header {
+  background: #99ccff;
 }
-.xv-grid-box .xv-scroller {
+.xv-list .xv-list-item .xv-list-item-gear {
+  position: absolute;
+  right: 0px;
+  z-index: 999;
+}
+.xv-list.xv-grid-list {
   background: #f8f8f8;
 }
-.xv-limit-description .xv-grid-box .xv-grid-attr.bold {
-  font-weight: bold;
+.xv-list.xv-grid-list .xv-list-item > * {
+  vertical-align: top;
 }
-.xv-grid-box .xv-grid-attr.error {
-  color: #ff0000;
+.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.emphasis {
-  color: #009000;
+.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.warn {
-  color: #ff9c00;
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr {
+  color: #fdfdfd;
 }
-.xv-grid-box .xv-grid-attr.italic {
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.placeholder {
   font-style: italic;
+  color: #99ccff;
 }
-.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.hyperlink {
+  color: #ff6529;
 }
-.xv-grid-box .xv-grid-attr.hyperlink {
-  color: blue;
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.header {
+  background: #99ccff;
 }
-.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 {
+  vertical-align: top;
 }
-.xv-grid-box .xv-grid-row {
+.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr {
   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-list.xv-grid-list .xv-list-item .xv-list-column.last {
+  border-right: none;
 }
-.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.name-column {
+  padding-left: 7px;
 }
-.xv-grid-box .xv-grid-row .xv-grid-header.last {
-  border-right: none;
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.first {
+  padding-left: 7px;
 }
-.xv-grid-box .xv-grid-row > * {
-  padding: 6px 4px;
-  border: none;
+.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 > * {
+  padding: 6px 4px;
+  border: none;
 }
 .xv-grid-box .xv-grid-row .line-number {
   vertical-align: top;
@@ -2653,6 +2928,7 @@ a,
 .selectable-chart .chart-title-bar .icon-filter {
   color: #070707;
   position: absolute;
+  top: 0;
   right: 35px;
 }
 .selectable-chart .chart-bottom {
 .selectable-chart .chart-filterDrawer {
   top: 0px;
 }
-/**
-  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;
+.selectable-chart .map-cluster {
+  width: 40px;
+  height: 40px;
+  background-color: greenyellow;
+  text-align: center;
+  font-size: 24px;
 }
 /**
   Styles relating to widgets in the pullout
index dff7f03..e7ccd5e 100644 (file)
@@ -56,6 +56,12 @@ trailing:true, white:true*/
         autoDismiss: false, modal: true, floating: true, scrim: true},
       {name: "navigator", kind: "XV.Navigator"}
     ],
+    resizeHandler: function () {
+      this.inherited(arguments);
+      if (this.$.notifyPopup.showing) {
+        this.$.notifyPopup.applyStyle("opacity", 1); // XXX not sure why this hack is necessary.
+      }
+    },
     activate: function () {
       this.goToNavigator();
       this.$.navigator.activate();
index a9b6694..0943f00 100644 (file)
@@ -77,6 +77,11 @@ select xt.install_js('XT','Discovery','xtuple', $$
       master.description = "Lets you get and manipulate all xTuple ERP business objects.";
       master.discoveryRestUrl = rootUrl + org + "/discovery/" + version + "/apis/" + version + "/rest";
       master.discoveryLink = "./apis/" + version + "/rest";
+      master.parameters = {
+        "resources": "object",
+        "description": "A query parameter array of resources you want to return. Useful for requesting a subset of resources instead of all of them. e.g. ?resources[]=Contact&resources[]=ToDo",
+        "location": "query"
+      };
       master.icons = {
         "x16": rootUrl + org + "/assets/api/api-16.png",
         "x32": rootUrl + org + "/assets/api/api-32.png"
@@ -586,8 +591,8 @@ select xt.install_js('XT','Discovery','xtuple', $$
           "query": {
             "type": "object",
             "description": "Query different resource properties based on their JSON-Schema. e.g. ?query[property1][BEGINS_WITH]=foo&query[property2][EQUALS]=bar",
-            "location": "query",
-            "$ref": "TODO: add this when moving to JSON-Schema draft v5"
+            "location": "query"
+            //"$ref": "TODO: add this when moving to JSON-Schema draft v5"
           },
           "orderby": {
             "type": "object",
@@ -651,8 +656,8 @@ select xt.install_js('XT','Discovery','xtuple', $$
           "query": {
             "type": "object",
             "description": "Query different resource properties based on their JSON-Schema. e.g. ?query[property1][BEGINS_WITH]=foo&query[property2][EQUALS]=bar",
-            "location": "query",
-            "$ref": "TODO"
+            "location": "query"
+            //"$ref": "TODO"
           },
           "orderby": {
             "type": "object",
@@ -790,6 +795,8 @@ select xt.install_js('XT','Discovery','xtuple', $$
         if (typeof method === 'function' && method.description && method.schema) {
           for (var schema in method.schema) {
             schemas[schema] = method.schema[schema];
+            schemas[schema].id = schema;
+            schemas[schema].type = 'object';
           }
         }
       }
index debd3c6..5115c1d 100644 (file)
@@ -289,7 +289,7 @@ select xt.install_js('XT','Schema','xtuple', $$
         nkey = XT.Orm.naturalKey(orm),
         pkey = XT.Orm.primaryKey(orm),
         prop,
-        ret = {},
+        ret = {"id": orm.type, "type": "object"},
         relatedORM = {},
         relatedKey,
         relatedKeyProp,
index 24b40e3..611107a 100644 (file)
@@ -36,79 +36,42 @@ var _ = require('underscore'),
     var buildSpecs = {},
       databases = [],
       extension,
-      //
-      // Looks in a database to see which extensions are registered, and
-      // tacks onto that list the core directories.
-      //
       getRegisteredExtensions = function (database, callback) {
-        var result,
-          credsClone = JSON.parse(JSON.stringify(creds)),
-          existsSql = "select relname from pg_class where relname = 'ext'",
-          preInstallSql = "select xt.js_init();update xt.ext set ext_location = '/core-extensions' " +
-            "where ext_name = 'oauth2' and ext_location = '/xtuple-extensions';",
-          extSql = preInstallSql + "SELECT * FROM xt.ext ORDER BY ext_load_order",
-          defaultExtensions = [
-            { ext_location: '/core-extensions', ext_name: 'crm' },
-            { ext_location: '/core-extensions', ext_name: 'project' },
-            { ext_location: '/core-extensions', ext_name: 'sales' },
-            { ext_location: '/core-extensions', ext_name: 'billing' },
-            { ext_location: '/core-extensions', ext_name: 'purchasing' },
-            { ext_location: '/core-extensions', ext_name: 'oauth2' }
-          ],
-          adaptExtensions = function (err, res) {
-            if (err) {
-              callback(err);
-              return;
-            }
-
-            var paths = _.map(_.compact(res.rows), function (row) {
-              var location = row.ext_location,
-                name = row.ext_name,
-                extPath;
-
-              if (location === '/core-extensions') {
-                extPath = path.join(__dirname, "/../../enyo-client/extensions/source/", name);
-              } else if (location === '/xtuple-extensions') {
-                extPath = path.join(__dirname, "../../../xtuple-extensions/source", name);
-              } else if (location === '/private-extensions') {
-                extPath = path.join(__dirname, "../../../private-extensions/source", name);
-              } else if (location === 'npm') {
-                extPath = path.join(__dirname, "../../node_modules", name);
-              }
-              return extPath;
-            });
-
-            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
-            callback(null, {
-              extensions: _.compact(paths),
-              database: database,
-              keepSql: options.keepSql,
-              populateData: options.populateData,
-              wipeViews: options.wipeViews,
-              clientOnly: options.clientOnly,
-              databaseOnly: options.databaseOnly
-            });
-          };
-
+        var credsClone = JSON.parse(JSON.stringify(creds));
         credsClone.database = database;
-        dataSource.query(existsSql, credsClone, function (err, res) {
-          if (err) {
-            callback(err);
-            return;
-          }
-          if (res.rowCount === 0) {
-            // xt.ext doesn't exist, because this is probably a brand-new DB.
-            // No problem! Give them the core extensions.
-            adaptExtensions(null, { rows: defaultExtensions });
-          } else {
-            dataSource.query(extSql, credsClone, adaptExtensions);
-          }
+        buildDatabaseUtil.inspectDatabaseExtensions(credsClone, function (err, paths) {
+          callback(null, {
+            extensions: paths,
+            database: database,
+            keepSql: options.keepSql,
+            populateData: options.populateData,
+            wipeViews: options.wipeViews,
+            clientOnly: options.clientOnly,
+            databaseOnly: options.databaseOnly
+          });
         });
       },
       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
@@ -118,7 +81,7 @@ var _ = require('underscore'),
               return _.flatten(memo);
             }, []);
             var npmExtensions = _.filter(allExtensions, function (extName) {
-              return extName.indexOf("node_modules") >= 0;
+              return extName && extName.indexOf("node_modules") >= 0;
             });
             if (npmExtensions.length === 0) {
               done();
@@ -165,13 +128,10 @@ var _ = require('underscore'),
       },
       config;
 
-    // the config path is not relative if it starts with a slash
-    if (options.config && options.config.substring(0, 1) === '/') {
-      config = require(options.config);
-    } else if (options.config) {
-      config = require(path.join(process.cwd(), options.config));
+    if (options.config) {
+      config = require(path.resolve(process.cwd(), options.config));
     } else {
-      config = require(path.join(__dirname, "../../node-datasource/config.js"));
+      config = require(path.resolve(__dirname, "../../node-datasource/config.js"));
     }
     creds = config.databaseServer;
     creds.encryptionKeyFile = config.datasource.encryptionKeyFile;
@@ -193,6 +153,9 @@ var _ = require('underscore'),
     } else if (options.backup && options.source) {
       callback("You can build from backup or from source but not both.");
 
+    } else if (options.backup && options.extension) {
+      callback("When you're building from a backup you get whatever extensions the backup merits.");
+
     } else if (options.initialize &&
         (options.backup || options.source) &&
         options.database &&
@@ -203,16 +166,17 @@ var _ = require('underscore'),
 
       buildSpecs.database = options.database;
       if (options.backup) {
-        // the backup path is not relative if it starts with a slash
-        buildSpecs.backup = options.backup.substring(0, 1) === '/' ?
-          options.backup :
-          path.join(process.cwd(), options.backup);
+        buildSpecs.backup = path.resolve(process.cwd(), options.backup);
+        buildSpecs.extensions = false;
+        // we'll determine the extensions by looking at the db after restore
       }
       if (options.source) {
-        // the source path is not relative if it starts with a slash
-        buildSpecs.source = options.source.substring(0, 1) === '/' ?
-          options.source :
-          path.join(process.cwd(), options.source);
+        buildSpecs.source = path.resolve(process.cwd(), options.source);
+        // if we initialize with the foundation, that means we want
+        // an unmobilized build
+        buildSpecs.extensions = options.extension ?
+          [options.extension] :
+          buildDatabaseUtil.defaultExtensions;
       }
       buildSpecs.initialize = true;
       buildSpecs.keepSql = options.keepSql;
@@ -220,19 +184,6 @@ var _ = require('underscore'),
       buildSpecs.wipeViews = options.wipeViews;
       buildSpecs.clientOnly = options.clientOnly;
       buildSpecs.databaseOnly = options.databaseOnly;
-      // if we initialize with the foundation, that means we want
-      // an unmobilized build
-      buildSpecs.extensions = options.extension ? [options.extension] : [
-        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')
-      ];
       buildAll([buildSpecs], creds, callback);
 
     } else if (options.initialize || options.backup || options.source) {
@@ -244,10 +195,7 @@ var _ = require('underscore'),
       // the user has specified an extension to build or unregister
       // extensions are assumed to be specified relative to the cwd
       buildSpecs = _.map(databases, function (database) {
-        // the extension is not relative if it starts with a slash
-        var extension = options.extension.substring(0, 1) === '/' ?
-          options.extension :
-          path.join(process.cwd(), options.extension);
+        var extension = path.resolve(process.cwd(), options.extension);
         return {
           database: database,
           frozen: options.frozen,
index d86e089..aadd5d0 100644 (file)
@@ -44,29 +44,6 @@ var  async = require('async'),
         host: 'localhost' }
   */
   var buildDatabase = exports.buildDatabase = function (specs, creds, masterCallback) {
-    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) {
-        if (err) {
-          winston.error("Init database error: ", err);
-          masterCallback(err);
-          return;
-        }
-        // recurse to do the build step. Of course we don't want to initialize a second
-        // time, so destroy those flags.
-        specs[0].initialize = false;
-        specs[0].wasInitialized = true;
-        specs[0].backup = undefined;
-        specs[0].source = undefined;
-        buildDatabase(specs, creds, masterCallback);
-      });
-      return;
-    }
-
     //
     // The function to generate all the scripts for a database
     //
@@ -82,7 +59,6 @@ var  async = require('async'),
           extensionCallback(null, "");
           return;
         }
-        //console.log("Installing extension", databaseName, extension);
         // deal with directory structure quirks
         var baseName = path.basename(extension),
           isFoundation = extension.indexOf("foundation-database") >= 0,
index e2da5e7..c8f5ca5 100644 (file)
@@ -14,8 +14,17 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
     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"),
@@ -376,6 +385,71 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
     });
   };
 
+  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
@@ -416,7 +490,7 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
           if (err) {
             console.log("ignoring restore db error", err);
           }
-          callback(null, res);
+          done(null, res);
         });
       },
       finish = function (err, results) {
@@ -437,7 +511,15 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
       async.series([
         dropDatabase,
         createDatabase,
-        restoreBackup
+        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);
     }
   };
@@ -524,6 +606,8 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */
     async.each(specs, unregisterEach, masterCallback);
   };
 
+  exports.defaultExtensions = defaultExtensions;
+  exports.inspectDatabaseExtensions = inspectDatabaseExtensions;
   exports.explodeManifest = explodeManifest;
   exports.initDatabase = initDatabase;
   exports.sendToDatabase = sendToDatabase;
index 4853c2b..f41f001 100644 (file)
@@ -1,5 +1,5 @@
-<package id        = "distribution-install-452"
-         version   = "4.5.2"
+<package id        = "distribution-install-460-beta"
+         version   = "4.6.0Beta"
          developer = "xTuple"
          descrip   = "load PostBooks resources"
          updater   = "2.2.4" >
@@ -19,8 +19,8 @@
 
   <prerequisite type = "query"
                 name = "Checking for bad xTuple ERP database version" >
-    <query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.2' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
-    <message>This package may not be applied to a 4.5.2+ PostBooks database.
+    <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.0' AND fetchMetricText('ServerVersion')!='4.6.0-beta' AND fetchMetricText('ServerVersion')!='4.6.0RC';</query>
+    <message>This package may not be applied to a 4.6.0+ PostBooks database.
     </message>
   </prerequisite>
 
index 73c3541..3e8af87 100644 (file)
@@ -1,5 +1,5 @@
-<package id        = "distribution-upgrade-452"
-         version   = "4.5.2"
+<package id        = "distribution-upgrade-460-beta"
+         version   = "4.6.0Beta"
          developer = "xTuple"
          descrip   = "load PostBooks resources"
          updater   = "2.2.4" >
@@ -19,8 +19,8 @@
 
  <prerequisite type = "query"
                name = "Checking for bad xTuple ERP database version" >
-<query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.2' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
-    <message>This package may not be applied to a 4.5.2+ Distribution database.
+<query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.0' AND fetchMetricText('ServerVersion')!='4.6.0-beta' AND fetchMetricText('ServerVersion')!='4.6.0RC';</query>
+    <message>This package may not be applied to a 4.6.0+ Distribution database.
     </message>
   </prerequisite>
 
index 139692b..e36fe0e 100644 (file)
@@ -1,5 +1,5 @@
-<package id        = "postbooks-upgrade-452"
-         version   = "4.5.2"
+<package id        = "postbooks-upgrade-460-beta"
+         version   = "4.6.0Beta"
          developer = "xTuple"
          descrip   = "load PostBooks resources"
          updater   = "2.2.4" >
@@ -19,8 +19,8 @@
 
   <prerequisite type = "query"
                 name = "Checking for bad xTuple ERP database version" >
-    <query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.2' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
-    <message>This package may not be applied to a 4.5.2+ Postbooks database.
+    <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.0' AND fetchMetricText('ServerVersion')!='4.6.0-beta' AND fetchMetricText('ServerVersion')!='4.6.0RC';</query>
+    <message>This package may not be applied to a 4.6.0+ Postbooks database.
     </message>
   </prerequisite>
 
index 35c516f..0ae18bc 100644 (file)
@@ -1,5 +1,5 @@
-<package id        = "manufacturing-install-452"
-         version   = "4.5.2"
+<package id        = "manufacturing-install-460-beta"
+         version   = "4.6.0Beta"
          developer = "xTuple"
          descrip   = "load PostBooks resources"
          updater   = "2.2.4" >
@@ -19,8 +19,8 @@
 
   <prerequisite type = "query"
                 name = "Checking for bad xTuple ERP database version" >
-    <query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.2' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
-    <message>This package may not be applied to a 4.5.2+ PostBooks database.
+    <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.0' AND fetchMetricText('ServerVersion')!='4.6.0-beta' AND fetchMetricText('ServerVersion')!='4.6.0RC';</query>
+    <message>This package may not be applied to a 4.6.0+ Distribution database.
     </message>
   </prerequisite>
 
index 47f5068..09594d2 100644 (file)
@@ -1,5 +1,5 @@
-<package id        = "manufacturing-upgrade-452"
-         version   = "4.5.2"
+<package id        = "manufacturing-upgrade-460-beta"
+         version   = "4.6.0Beta"
          developer = "xTuple"
          descrip   = "load PostBooks resources"
          updater   = "2.2.4" >
@@ -30,8 +30,8 @@
 
 <prerequisite type = "query"
                name = "Checking for bad xTuple ERP database version" >
-<query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.2' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
-    <message>This package may not be applied to a 4.5.2+ Manufacturing database.
+<query>SELECT NOT fetchMetricText('ServerVersion') > '4.6.0-beta9' AND fetchMetricText('ServerVersion') != '4.6.0';</query>
+    <message>This package may not be applied to a 4.6.0+ Manufacturing database.
     </message>
 </prerequisite>