From: Gil Moskowitz Date: Thu, 18 Sep 2014 13:55:53 +0000 (-0400) Subject: Merge pull request #1831 from garyhgohoos/24544 X-Git-Tag: v4.7.0-beta.2~14 X-Git-Url: http://git.roojs.org/?a=commitdiff_plain;h=53b3f36f7a8c1b6752cb69b694d3bc36c04bb917;hp=49b3c090ad35b0a41a81db9065b420f522f08ef6;p=xtuple Merge pull request #1831 from garyhgohoos/24544 Issue #24544:display posted date rather than create date --- diff --git a/.travis.yml b/.travis.yml index 7d0d3a4a3..564ef540d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "0.8" + - "0.10" install: - "bash scripts/install_xtuple.sh -ipn" @@ -15,7 +15,3 @@ script: - "npm run-script test-datasource" - "npm run-script test" - "npm run-script jshint" - - # test an upgrade from 4.4.0 - - "wget http://sourceforge.net/projects/postbooks/files/03%20PostBooks-databases/4.4.0/postbooks_demo-4.4.0.backup" - - "./scripts/build_app.js -d upgrade_test -i -b ./postbooks_demo-4.4.0.backup" diff --git a/enyo-client/application/source/views/module_container.js b/enyo-client/application/source/views/module_container.js index 8c494776d..4cc5a4c54 100644 --- a/enyo-client/application/source/views/module_container.js +++ b/enyo-client/application/source/views/module_container.js @@ -84,7 +84,5 @@ trailing:true, white:true*/ } }); } - }); - }()); diff --git a/enyo-client/application/source/views/workspace.js b/enyo-client/application/source/views/workspace.js index d164ff4c4..f74658d97 100644 --- a/enyo-client/application/source/views/workspace.js +++ b/enyo-client/application/source/views/workspace.js @@ -3343,5 +3343,4 @@ strict: false*/ XV.registerModelWorkspace("XM.UserAccountRoleRelation", "XV.UserAccountRoleWorkspace"); XV.registerModelWorkspace("XM.UserAccountRoleListItem", "XV.UserAccountRoleWorkspace"); - }()); diff --git a/enyo-client/database/source/delete_system_orms.sql b/enyo-client/database/source/delete_system_orms.sql index dc1cfbc9c..79e2b31e9 100644 --- a/enyo-client/database/source/delete_system_orms.sql +++ b/enyo-client/database/source/delete_system_orms.sql @@ -2,19 +2,6 @@ DO $$ /* Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. See www.xm.ple.com/CPAL for the full text of the software license. */ - var result, - viewname, - schemaname, - i; - - sql = "select schemaname, viewname from pg_views where schemaname in ('xm','sys', 'xt');" - result = plv8.execute(sql); - for (i = 0; i < result.length; i++) { - viewname = result[i].viewname; - schemaname = result[i].schemaname; - plv8.execute('drop view if exists ' + schemaname + '.' + viewname + ' cascade;'); - } - plv8.execute("select xt.js_init()"); plv8.execute("alter table xt.orm disable trigger orm_did_change"); plv8.execute("delete from xt.orm where orm_json ~ '\"isSystem\":true';"); diff --git a/enyo-client/database/source/wipe_views.sql b/enyo-client/database/source/wipe_views.sql new file mode 100644 index 000000000..87ec0d33f --- /dev/null +++ b/enyo-client/database/source/wipe_views.sql @@ -0,0 +1,19 @@ +DO $$ + /* Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. + See www.xm.ple.com/CPAL for the full text of the software license. */ + + var sql, + result, + viewname, + schemaname, + i; + + sql = "select schemaname, viewname from pg_views where schemaname in ('xm','sys', 'xt');" + result = plv8.execute(sql); + for (i = 0; i < result.length; i++) { + viewname = result[i].viewname; + schemaname = result[i].schemaname; + plv8.execute('drop view if exists ' + schemaname + '.' + viewname + ' cascade;'); + } + +$$ language plv8; diff --git a/enyo-client/database/source/xt/functions/cust_outstanding_credit.sql b/enyo-client/database/source/xt/functions/cust_outstanding_credit.sql index fa626f840..6aa15dbe0 100644 --- a/enyo-client/database/source/xt/functions/cust_outstanding_credit.sql +++ b/enyo-client/database/source/xt/functions/cust_outstanding_credit.sql @@ -18,7 +18,7 @@ from ( where aropen_cust_id = $1 and aropen_open --and aropen_posted = false - group by aropen_id + group by aropen_id, aropen_cust_id, aropen_curr_id, aropen_amount ) unalloc; $$ language sql; diff --git a/enyo-client/extensions/source/billing/database/source/xt/tables/rptdef.sql b/enyo-client/extensions/source/billing/database/source/xt/tables/rptdef.sql index ecd07aa94..938c9d367 100644 --- a/enyo-client/extensions/source/billing/database/source/xt/tables/rptdef.sql +++ b/enyo-client/extensions/source/billing/database/source/xt/tables/rptdef.sql @@ -1,4 +1,4 @@ -select xt.add_report_definition('XM.Invoice', 0, $${ +select xt.add_report_definition('XM.Invoice', 0, $${ "settings": { "detailAttribute": "lineItems", "defaultFontSize": 12, @@ -151,12 +151,31 @@ select xt.add_report_definition('XM.Invoice', 0, $${ }, {"element": "bandLine", "size": 2}, { + "element": "band", "definition": [ - {"attr": "subtotal", "label": true}, - {"attr": "taxTotal", "label": true}, - {"attr": "total", "label": true} + {"text": "_subtotal", "label": true, "width": 70, "align": "left"}, + {"attr": "subtotal", "width": 100, "align": "right"} ], - "options": {"width": 525, "align": "right"} + "options": {"border": 0, "x": 360} + }, + { + "element": "band", + "definition": [ + {"text": "_taxTotal", "label": true, "width": 70, "align": "left"}, + {"attr": "taxTotal", "width": 100, "align": "right"} + ], + "options": {"border": 0, "x": 360} + }, + { + "element": "band", + "definition": [ + {"text": "_total", "label": true, "width": 70, "align": "left"}, + {"attr": "total", "width": 100, "align": "right"} + ], + "options": {"border": 0, "x": 360} + }, + { + "definition": [] } ], "pageFooterElements": [ diff --git a/enyo-client/extensions/source/oauth2/client/en/strings.js b/enyo-client/extensions/source/oauth2/client/en/strings.js index f34b60283..fc5d4e398 100644 --- a/enyo-client/extensions/source/oauth2/client/en/strings.js +++ b/enyo-client/extensions/source/oauth2/client/en/strings.js @@ -17,9 +17,9 @@ strict:true, trailing:true, white:true */ "_issued": "Issued", "_fullListUrl": "Full List URL", "_generatingPrivateKey": "A new keypair will be generated for this OAUTH2 client. " + - "The public key will be saved in the database with this client. The private key " + - "is available as a one-time download. The password for the key store file will be " + - "\"notasecret\". Click \"ok\" to downloading the private key.", + "The public key will be available in the future with this client. The private key " + + "is only available now as a one-time download. Note that this process can take up " + + "to a minute. Please wait until the key is downloaded.", "_logoURL": "Logo URL", "_maintainOauth2clients": "Maintain OAUTH2 Clients", "_oauth2": "OAUTH2", diff --git a/foundation-database/public/functions/convertquote.sql b/foundation-database/public/functions/convertquote.sql index bf15b9bf0..c9d775989 100644 --- a/foundation-database/public/functions/convertquote.sql +++ b/foundation-database/public/functions/convertquote.sql @@ -4,6 +4,8 @@ CREATE OR REPLACE FUNCTION convertQuote(INTEGER) RETURNS INTEGER AS $$ -- See www.xtuple.com/CPAL for the full text of the software license. DECLARE pQuheadid ALIAS FOR $1; + _qunumber TEXT; + _ponumber TEXT; _soheadid INTEGER; _soitemid INTEGER; _orderid INTEGER; @@ -62,13 +64,20 @@ BEGIN RETURN -5; END IF; - IF ( (_usespos) AND (NOT _blanketpos) ) THEN - PERFORM cohead_id - FROM quhead JOIN cohead ON ( (cohead_cust_id=quhead_cust_id) AND - (UPPER(cohead_custponumber)=UPPER(quhead_custponumber)) ) + IF (_usespos) THEN + SELECT quhead_number, COALESCE(quhead_custponumber, ''), cohead_id INTO _qunumber, _ponumber, _soheadid + FROM quhead LEFT OUTER JOIN cohead ON ( (cohead_cust_id=quhead_cust_id) AND + (UPPER(cohead_custponumber)=UPPER(quhead_custponumber)) ) WHERE (quhead_id=pQuheadid); - IF (FOUND) THEN - RAISE EXCEPTION 'Duplicate Customer PO'; + IF (_ponumber = '') THEN + RAISE EXCEPTION 'Customer PO required for Quote % [xtuple: convertQuote, -7, %]', + _qunumber, _qunumber; + END IF; + + IF ( (NOT _blanketpos) AND (_soheadid IS NOT NULL) ) THEN + RAISE EXCEPTION 'Duplicate Customer PO % for Quote % [xtuple: convertQuote, -8, %, %]', + _ponumber, _qunumber, + _ponumber, _qunumber; END IF; END IF; @@ -180,7 +189,7 @@ BEGIN AND (comment_source_id=pQuheadid) ); FOR _r IN SELECT quitem.*, - quhead_number, quhead_prj_id, + quhead_number, quhead_prj_id, quhead_saletype_id, itemsite_item_id, itemsite_leadtime, itemsite_createsopo, itemsite_createsopr, item_type, COALESCE(quitem_itemsrc_id, itemsrc_id, -1) AS itemsrcid @@ -215,7 +224,8 @@ BEGIN IF (fetchMetricBool('enablextcommissionission')) THEN PERFORM xtcommission.getSalesReps(quhead_cust_id, quhead_shipto_id, - _r.itemsite_item_id, _r.quitem_price, + _r.itemsite_item_id, _r.quhead_saletype_id, + _r.quitem_price, _r.quitem_custprice, _soitemid, 'SalesItem') FROM quhead WHERE (quhead_id=pQuheadid); @@ -242,8 +252,10 @@ BEGIN IF (_r.quitem_createorder) THEN IF (_r.item_type IN ('M')) THEN - SELECT createWo( CAST(_r.quhead_number AS INTEGER), supply.itemsite_id, 1, (_r.quitem_qtyord * _r.quitem_qty_invuomratio), - _r.itemsite_leadtime, _r.quitem_scheddate, _r.quitem_memo, 'S', _soitemid, _r.quhead_prj_id ) INTO _orderId + SELECT createWo( CAST(_soNum AS INTEGER), supply.itemsite_id, 1, + (_r.quitem_qtyord * _r.quitem_qty_invuomratio), + _r.itemsite_leadtime, _r.quitem_scheddate, _r.quitem_memo, + 'S', _soitemid, _r.quhead_prj_id ) INTO _orderId FROM itemsite sold, itemsite supply WHERE ((sold.itemsite_item_id=supply.itemsite_item_id) AND (supply.itemsite_warehous_id=_r.quitem_order_warehous_id) @@ -258,7 +270,8 @@ BEGIN AND (charass_target_id=_r.quitem_id)); ELSIF ( (_r.item_type IN ('P', 'O')) AND (_r.itemsite_createsopr) ) THEN - SELECT createPr( CAST(_r.quhead_number AS INTEGER), _r.quitem_itemsite_id, (_r.quitem_qtyord * _r.quitem_qty_invuomratio), + SELECT createPr( CAST(_soNum AS INTEGER), _r.quitem_itemsite_id, + (_r.quitem_qtyord * _r.quitem_qty_invuomratio), _r.quitem_scheddate, '', 'S', _soitemid ) INTO _orderId; _orderType := 'R'; UPDATE pr SET pr_prj_id=_r.quhead_prj_id WHERE pr_id=_orderId; diff --git a/foundation-database/public/functions/convertquotetoinvoice.sql b/foundation-database/public/functions/convertquotetoinvoice.sql index 5c68dc281..22c8c211f 100644 --- a/foundation-database/public/functions/convertquotetoinvoice.sql +++ b/foundation-database/public/functions/convertquotetoinvoice.sql @@ -4,6 +4,8 @@ CREATE OR REPLACE FUNCTION convertQuoteToInvoice(INTEGER) RETURNS INTEGER AS $$ -- See www.xtuple.com/CPAL for the full text of the software license. DECLARE pQuheadid ALIAS FOR $1; + _qunumber TEXT; + _ponumber TEXT; _iheadid INTEGER; _iitemid INTEGER; _orderid INTEGER; @@ -67,17 +69,47 @@ BEGIN END IF; -- PO/blanket PO checks + IF (_usespos) THEN + SELECT quhead_number, COALESCE(quhead_custponumber, ''), invchead_id INTO _qunumber, _ponumber, _iheadid + FROM quhead LEFT OUTER JOIN invchead ON ( (invchead_cust_id=quhead_cust_id) AND + (UPPER(invchead_ponumber)=UPPER(quhead_custponumber)) ) + WHERE (quhead_id=pQuheadid); + IF (_ponumber = '') THEN + RAISE EXCEPTION 'Customer PO required for Quote % [xtuple: convertQuote, -7, %]', + _qunumber, _qunumber; + END IF; + + IF ( (NOT _blanketpos) AND (_iheadid IS NOT NULL) ) THEN + RAISE EXCEPTION 'Duplicate Customer PO % for Quote % [xtuple: convertQuote, -8, %, %]', + _ponumber, _qunumber, + _ponumber, _qunumber; + END IF; + END IF; + + IF (_usespos) THEN + SELECT quhead_number INTO _qunumber + FROM quhead + WHERE (quhead_id=pQuheadid) + AND (COALESCE(quhead_custponumber, '') = ''); + IF (FOUND) THEN + RAISE EXCEPTION 'Customer PO required for Quote % [xtuple: convertQuote, -7, %]', + _qunumber, _qunumber; + END IF; + END IF; + IF ( (_usespos) AND (NOT _blanketpos) ) THEN - PERFORM invchead_id + SELECT quhead_number, quhead_custponumber INTO _qunumber, _ponumber FROM quhead JOIN invchead ON ( (invchead_cust_id=quhead_cust_id) AND - (UPPER(invchead_custponumber)=UPPER(quhead_custponumber)) ) + (UPPER(invchead_ponumber)=UPPER(quhead_custponumber)) ) WHERE (quhead_id=pQuheadid); IF (FOUND) THEN - RAISE EXCEPTION 'Duplicate Customer PO'; + RAISE EXCEPTION 'Duplicate Customer PO % for Quote % [xtuple: convertQuote, -8, %, %]', + _ponumber, _qunumber, + _ponumber, _qunumber; END IF; END IF; - + --Check to see if an invoice exists with the quote number PERFORM quhead_number, invchead_id @@ -182,7 +214,7 @@ BEGIN */ FOR _r IN SELECT quitem.*, - quhead_number, quhead_prj_id, + quhead_number, quhead_prj_id, quhead_saletype_id, itemsite_item_id, itemsite_leadtime, itemsite_createsopo, itemsite_createsopr, item_type, COALESCE(quitem_itemsrc_id, itemsrc_id, -1) AS itemsrcid @@ -220,7 +252,8 @@ BEGIN IF (fetchMetricBool('enablextcommissionission')) THEN PERFORM xtcommission.getSalesReps(quhead_cust_id, quhead_shipto_id, - _r.itemsite_item_id, _r.quitem_price, + _r.itemsite_item_id, _r.quhead_saletype_id, + _r.quitem_price, _r.quitem_custprice, _iitemid, 'InvoiceItem') FROM quhead WHERE (quhead_id=pQuheadid); diff --git a/foundation-database/public/functions/createpurchasetosale.sql b/foundation-database/public/functions/createpurchasetosale.sql index d52a6ea0d..31d3ac7ea 100644 --- a/foundation-database/public/functions/createpurchasetosale.sql +++ b/foundation-database/public/functions/createpurchasetosale.sql @@ -15,7 +15,7 @@ BEGIN RETURN createPurchaseToSale(pCoitemId, pItemSourceId, pDropShip, NULL, NULL, NULL); END; -$$ LANGUAGE 'plpgsql'; +$$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION createPurchaseToSale(INTEGER, INTEGER, BOOLEAN, NUMERIC) RETURNS INTEGER AS $$ @@ -32,7 +32,7 @@ BEGIN RETURN createPurchaseToSale(pCoitemId, pItemSourceId, pDropShip, NULL, NULL, pPrice); END; -$$ LANGUAGE 'plpgsql'; +$$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION createPurchaseToSale(INTEGER, INTEGER, BOOLEAN, NUMERIC, DATE, NUMERIC) RETURNS INTEGER AS $$ @@ -51,7 +51,7 @@ BEGIN RETURN createPurchaseToSale(pCoitemId, pItemSourceId, pDropShip, pQty, pDueDate, pPrice, NULL); END; -$$ LANGUAGE 'plpgsql'; +$$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION createPurchaseToSale(INTEGER, INTEGER, BOOLEAN, NUMERIC, DATE, NUMERIC, INTEGER) RETURNS INTEGER AS $$ @@ -126,27 +126,27 @@ BEGIN FROM pohead WHERE ( (pohead_status = 'U') AND (pohead_vend_id = _i.itemsrc_vend_id) - AND (pohead_shiptoname = COALESCE(_s.cohead_shiptoname, _s.shipto_name, '')) - AND (pohead_shiptoaddress1 = COALESCE(_s.cohead_shiptoaddress1, _s.addr_line1, '')) - AND (pohead_shiptoaddress2 = COALESCE(_s.cohead_shiptoaddress2, _s.addr_line2, '')) - AND (pohead_shiptoaddress3 = COALESCE(_s.cohead_shiptoaddress3, _s.addr_line3, '')) - AND (pohead_shiptocity = COALESCE(_s.cohead_shiptocity, _s.addr_city, '')) - AND (pohead_shiptostate = COALESCE(_s.cohead_shiptostate, _s.addr_state, '')) - AND (pohead_shiptozipcode = COALESCE(_s.cohead_shiptozipcode, _s.addr_postalcode, '')) - AND (pohead_shiptocountry = COALESCE(_s.cohead_shiptocountry, _s.addr_country, '')) + AND (COALESCE(pohead_shiptoname, '') = COALESCE(_s.cohead_shiptoname, _s.shipto_name, '')) + AND (COALESCE(pohead_shiptoaddress1, '') = COALESCE(_s.cohead_shiptoaddress1, _s.addr_line1, '')) + AND (COALESCE(pohead_shiptoaddress2, '') = COALESCE(_s.cohead_shiptoaddress2, _s.addr_line2, '')) + AND (COALESCE(pohead_shiptoaddress3, '') = COALESCE(_s.cohead_shiptoaddress3, _s.addr_line3, '')) + AND (COALESCE(pohead_shiptocity, '') = COALESCE(_s.cohead_shiptocity, _s.addr_city, '')) + AND (COALESCE(pohead_shiptostate, '') = COALESCE(_s.cohead_shiptostate, _s.addr_state, '')) + AND (COALESCE(pohead_shiptozipcode, '') = COALESCE(_s.cohead_shiptozipcode, _s.addr_postalcode, '')) + AND (COALESCE(pohead_shiptocountry, '') = COALESCE(_s.cohead_shiptocountry, _s.addr_country, '')) AND ((pohead_id=pPoheadId) OR (pPoheadid IS NULL)) ); ELSE SELECT COALESCE(pohead_id, -1) INTO _temp FROM pohead WHERE ( (pohead_status = 'U') AND (pohead_vend_id = _i.itemsrc_vend_id) - AND (pohead_shiptoaddress1 = COALESCE(_w.addr_line1, '')) - AND (pohead_shiptoaddress2 = COALESCE(_w.addr_line2, '')) - AND (pohead_shiptoaddress3 = COALESCE(_w.addr_line3, '')) - AND (pohead_shiptocity = COALESCE(_w.addr_city, '')) - AND (pohead_shiptostate = COALESCE(_w.addr_state, '')) - AND (pohead_shiptozipcode = COALESCE(_w.addr_postalcode, '')) - AND (pohead_shiptocountry = COALESCE(_w.addr_country, '')) + AND (COALESCE(pohead_shiptoaddress1, '') = COALESCE(_w.addr_line1, '')) + AND (COALESCE(pohead_shiptoaddress2, '') = COALESCE(_w.addr_line2, '')) + AND (COALESCE(pohead_shiptoaddress3, '') = COALESCE(_w.addr_line3, '')) + AND (COALESCE(pohead_shiptocity, '') = COALESCE(_w.addr_city, '')) + AND (COALESCE(pohead_shiptostate, '') = COALESCE(_w.addr_state, '')) + AND (COALESCE(pohead_shiptozipcode, '') = COALESCE(_w.addr_postalcode, '')) + AND (COALESCE(pohead_shiptocountry, '') = COALESCE(_w.addr_country, '')) AND ((pohead_id=pPoheadId) OR (pPoheadid IS NULL)) ); END IF; @@ -364,4 +364,4 @@ BEGIN RETURN _poitemid; END; -$$ LANGUAGE 'plpgsql' VOLATILE; +$$ LANGUAGE plpgsql VOLATILE; diff --git a/foundation-database/public/tables/bankrecimport.sql b/foundation-database/public/tables/bankrecimport.sql index de1fc7cce..c9c74c4ab 100644 --- a/foundation-database/public/tables/bankrecimport.sql +++ b/foundation-database/public/tables/bankrecimport.sql @@ -1,9 +1,9 @@ select xt.create_table('bankrecimport', 'public'); select xt.add_column('bankrecimport','bankrecimport_id', 'SERIAL', 'PRIMARY KEY', 'public'); -select xt.add_column('bankrecimport','bankrecimport_reference', 'TEXT', 'NOT NULL', 'public'); -select xt.add_column('bankrecimport','bankrecimport_descrip', 'TEXT', 'NOT NULL', 'public'); -select xt.add_column('bankrecimport','bankrecimport_comment', 'TEXT', 'NOT NULL', 'public'); -select xt.add_column('bankrecimport','bankrecimport_debit_amount', 'NUMERIC', 'NOT NULL', 'public'); -select xt.add_column('bankrecimport','bankrecimport_credit_amount', 'NUMERIC', 'NOT NULL', 'public'); -select xt.add_column('bankrecimport','bankrecimport_effdate', 'DATE', 'NOT NULL', 'public'); -select xt.add_column('bankrecimport','bankrecimport_curr_rate', 'NUMERIC', 'NOT NULL', 'public'); +select xt.add_column('bankrecimport','bankrecimport_reference', 'TEXT', NULL, 'public'); +select xt.add_column('bankrecimport','bankrecimport_descrip', 'TEXT', NULL, 'public'); +select xt.add_column('bankrecimport','bankrecimport_comment', 'TEXT', NULL, 'public'); +select xt.add_column('bankrecimport','bankrecimport_debit_amount', 'NUMERIC', NULL, 'public'); +select xt.add_column('bankrecimport','bankrecimport_credit_amount', 'NUMERIC', NULL, 'public'); +select xt.add_column('bankrecimport','bankrecimport_effdate', 'DATE', NULL, 'public'); +select xt.add_column('bankrecimport','bankrecimport_curr_rate', 'NUMERIC', NULL, 'public'); diff --git a/foundation-database/public/tables/metasql/billingSelections-detail.mql b/foundation-database/public/tables/metasql/billingSelections-detail.mql index 864b03bc2..66bfe7e5c 100644 --- a/foundation-database/public/tables/metasql/billingSelections-detail.mql +++ b/foundation-database/public/tables/metasql/billingSelections-detail.mql @@ -1,8 +1,8 @@ -- Group: billingSelections -- Name: detail -- Notes: used by dspBillingSelections --- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple. --- See www.xtuple.com/CPAL for the full text of the software license. +-- 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 cobmisc_id, cohead_id, cohead_number, cust_number, cust_name, @@ -21,7 +21,7 @@ FROM cobmisc, cohead, custinfo, coitem, cobill WHERE ((cobmisc_cohead_id=cohead_id) AND (cohead_cust_id=cust_id) AND (coitem_cohead_id=cohead_id) - AND (cobill_coitem_id=coitem_id) + AND (cobill_coitem_id=coitem_id) AND (COALESCE(cobill_invcnum,0) = 0) AND (NOT cobmisc_posted)) GROUP BY cobmisc_id, cohead_id, cohead_number, cust_number, cust_name, cobmisc_misc, cobmisc_freight, cobmisc_tax, cobmisc_payment diff --git a/foundation-database/public/tables/metasql/bookings-detail.mql b/foundation-database/public/tables/metasql/bookings-detail.mql index 28a6f0840..b8b5bf406 100644 --- a/foundation-database/public/tables/metasql/bookings-detail.mql +++ b/foundation-database/public/tables/metasql/bookings-detail.mql @@ -31,18 +31,11 @@ SELECT coitem_id AS id, coitem_cohead_id AS altId, (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2) AS baseextpricebalance, round((coitem_qtyord * coitem_qty_invuomratio) * (coitem_unitcost / coitem_price_invuomratio), 2) AS extcost, - (round((coitem_qtyord * coitem_qty_invuomratio) * - (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2) - - round((coitem_qtyord * coitem_qty_invuomratio) * - (coitem_unitcost / coitem_price_invuomratio), 2)) AS margin, - CASE WHEN (coitem_price > 0.0) THEN - (round((coitem_qtyord * coitem_qty_invuomratio) * - (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2) - - round((coitem_qtyord * coitem_qty_invuomratio) * - (coitem_unitcost / coitem_price_invuomratio), 2)) / - round((coitem_qtyord * coitem_qty_invuomratio) * - (currtobase(cohead_curr_id, coitem_price, cohead_orderdate) / coitem_price_invuomratio), 2) - ELSE 0.0 + CASE WHEN (coitem_price = 0.0) THEN 0.0 + ELSE ROUND(coitem_qtyord * coitem_qty_invuomratio * (coitem_price - coitem_unitcost) / coitem_price_invuomratio,2) + END AS margin, + CASE WHEN (coitem_price = 0.0) THEN 0.0 + ELSE ((coitem_price - coitem_unitcost) / coitem_price) END AS marginpercent, curr_abbr AS currAbbr, -- TODO - not needed, remove? (very slow) diff --git a/foundation-database/public/trigger_functions/usrpriv.sql b/foundation-database/public/trigger_functions/usrpriv.sql index 7ab00984e..b35a826d6 100644 --- a/foundation-database/public/trigger_functions/usrpriv.sql +++ b/foundation-database/public/trigger_functions/usrpriv.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION _usrprivTrigger() RETURNS TRIGGER AS $$ +CREATE OR REPLACE FUNCTION _usrprivTrigger() RETURNS TRIGGER 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 @@ -8,6 +8,13 @@ BEGIN -- This looks like a candidate for a foreign key but isn't. -- fkeys don't work if the foreign key value resides in a child of the -- table and not the table itself. + IF (NOT EXISTS(SELECT usrpriv_id + FROM usrpriv, priv + WHERE ((usrpriv_priv_id=priv_id) AND (priv_name ='MaintainUsers') + AND (usrpriv_username=geteffectivextuser())))) THEN + RAISE EXCEPTION 'User have no privileges to modify user privileges.'; + END IF; + IF ((TG_OP = 'UPDATE' OR TG_OP = 'INSERT') AND (NOT EXISTS(SELECT priv_id FROM priv diff --git a/lib/enyo-x/source/less/screen.less b/lib/enyo-x/source/less/screen.less index ffbd2a89c..a2371b63f 100644 --- a/lib/enyo-x/source/less/screen.less +++ b/lib/enyo-x/source/less/screen.less @@ -56,6 +56,9 @@ @defaultPanelWidth: 320px; @toolbarHeight: 55px; @searchLength: 185px; +// popups +@maxMessageHeight: 500px; +@maxMessageWidth: 500px; // libs @import "../../lib/font-awesome/less/font-awesome.less"; @@ -196,13 +199,16 @@ a, .hyperlink { */ .xv-popup { background: @header-gray; - margin: 0; - max-height: 400px; - width: 400px; min-width: @defaultPanelWidth; - padding: 7px; + padding: 10px; text-align: center; + .message { + margin-bottom: 10px; + max-height: @maxMessageHeight; + max-width: @maxMessageWidth; + } + &.xv-groupbox-popup { .xv-workspace-container > .xv-workspace > .xv-workspace-panel; color: @black; diff --git a/lib/enyo-x/source/stylesheets/screen.css b/lib/enyo-x/source/stylesheets/screen.css index 62aa1aa4f..f123de58a 100755 --- a/lib/enyo-x/source/stylesheets/screen.css +++ b/lib/enyo-x/source/stylesheets/screen.css @@ -1628,13 +1628,15 @@ a, */ .xv-popup { background: #505050; - margin: 0; - max-height: 400px; - width: 400px; min-width: 320px; - padding: 7px; + padding: 10px; text-align: center; } +.xv-popup .message { + margin-bottom: 10px; + max-height: 500px; + max-width: 500px; +} .xv-popup.xv-groupbox-popup { width: 320px; margin: 0 4px 0 2px; @@ -2222,437 +2224,162 @@ a, border: none; } /** - Styles relating to Lists -*/ -.xv-list-header { - background-color: #d8d8d8; - color: #fdfdfd; - font-size: .6em; - font-weight: bold; - text-transform: uppercase; - padding-top: 4px; - padding-bottom: 4px; - border-bottom: 1px solid #aaaaaa; + * Default ListItem styles when using a ModelDecorator. + */ +.xv-list .xv-model-decorator > .xv-list-item .xv-table { + display: table; + width: 100%; + table-layout: fixed; } -.xv-list-header .xv-list-column.last { - border-right: none; +.xv-list .xv-model-decorator > .xv-list-item .xv-table .xv-cell { + display: table-cell; } -.xv-list-header .xv-list-column.name-column, -.xv-list-header .xv-list-column.first, -.xv-list-header .xv-list-column.second, -.xv-list-header .xv-list-column.third, -.xv-list-header .xv-list-column.short, -.xv-list-header .xv-list-column.small, -.xv-list-header .xv-list-column.medium, -.xv-list-header .xv-list-column.descr { - padding-left: 7px; +.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr { + /** + * Default styling for a model's id (as designated by 'idAttribute') + */ } -/* List */ -.xv-list-column.line-number { - width: 30px; - text-align: right; +.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-id { + color: #357ec7; + font-weight: bold; + cursor: pointer; } -.xv-list-column.name-column { - width: 200px; +.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-name { + font-weight: bold; } -.xv-list-column.right-column { - width: 100px; +.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-number { text-align: right; } -.xv-list-column.short { - width: 100px; -} -.xv-list-column.small { - width: 125px; -} -.xv-list-column.medium { - width: 150px; -} -.xv-list-column.first { - width: 300px; +.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-money { + text-align: right; } -.xv-list-column.second { - width: 200px; +.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-date { + text-align: right; } -.xv-list-column.third { - width: 100px; +.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr { + color: white; } -.xv-list-column.money, -.xv-list-column.quantity { - width: 75px; - text-align: right; +.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr.xm-attribute-id { + color: #ff6529; } -.xv-list-column.descr { - width: 200px; +/** + Styles related to pickers, combo boxes, and relation widgets +*/ +.onyx-picker-decorator .onyx-button { + padding: 12px 8px 12px 8px; + width: 150px; } -.xv-list-column.icon { - width: 10px; +.onyx-picker .onyx-menu-item { + text-align: left; + text-overflow: ellipsis; } -.xv-list { - background: #f8f8f8; +.picker-icon { + position: absolute; + right: 0; + margin: 0 10px 0 2px; + color: #070707; } -.xv-list .xv-list-item > * { - display: inline-block; - vertical-align: middle; +.xv-picker-button { + text-align: left; } -.xv-list .xv-list-item { - background-color: #fdfdfd; - border-bottom: 1px solid #d7d7d7; - min-height: 32px; +.xv-picker-button .picker-content { + max-width: 100px; + overflow: hidden; } -.xv-list .xv-list-item.header { - padding-top: 0; +.xv-picker-button.disabled { + color: #777777; } -.xv-list .xv-list-item.inactive { - background-color: #d8d8d8; +.xv-picker-label { color: #070707; + padding: 20px 8px 8px 8px; + text-align: right; + width: 130px; } -.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr { - background: transparent; -} -.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr.placeholder { - color: #d8d8d8; +.xv-picker-label.disabled { + color: #777777; } -.xv-list .xv-list-item .xv-list-column .list-icon { - padding: 2px; - color: #666666; - vertical-align: sub; - border: 1px solid #efefef; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; +.xv-combobox-note { + padding: 14px 3px 8px 3px; + text-align: left; } -.xv-list .xv-list-item.item-selected { - background: #226b9a; - background-color: #1f608c; - background-image: -moz-linear-gradient(top, #226b9a, #1a4f77); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77)); - background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77); - background-image: -o-linear-gradient(top, #226b9a, #1a4f77); - background-image: linear-gradient(to bottom, #226b9a, #1a4f77); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0); +/* + Styles relating to the grid box +*/ +/* Entire box including the grid and the summary panel */ +.xv-grid-box { + /** + This is the most general grid row that + is not specific to read-only or selected + */ } -.xv-list .xv-list-item.item-selected .xv-list-attr { - color: #fdfdfd; +.xv-grid-box.small-panel { + width: 600px; } -.xv-list .xv-list-item.item-selected .xv-list-attr.placeholder { - font-style: italic; - color: #99ccff; +.xv-grid-box.medium-panel { + width: 700px; } -.xv-list .xv-list-item.item-selected .xv-list-attr.hyperlink { - color: #ff6529; +.xv-grid-box.large-panel { + width: 800px; } -.xv-list .xv-list-item.item-selected .xv-list-attr.header { - background: #99ccff; +.xv-grid-box .enyo-list-page > *:first-child .xv-grid-row { + border-top: 0; } -.xv-list .xv-list-item .xv-list-item-gear { - position: absolute; - right: 0px; - z-index: 999; +.xv-grid-box .xv-above-grid-list { + border: 0; } -.xv-list.xv-grid-list { +.xv-grid-box .xv-scroller { background: #f8f8f8; } -.xv-list.xv-grid-list .xv-list-item > * { - vertical-align: top; +.xv-limit-description .xv-grid-box .xv-grid-attr.bold { + font-weight: bold; } -.xv-list.xv-grid-list .xv-list-item { - padding-top: 7px !important; - padding-bottom: 9px !important; - border-bottom: 1px solid #aaaaaa !important; - background: #f8f8f8; +.xv-grid-box .xv-grid-attr.error { + color: #ff0000; } -.xv-list.xv-grid-list .xv-list-item.item-selected { - background: #226b9a; - background-color: #1f608c; - background-image: -moz-linear-gradient(top, #226b9a, #1a4f77); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77)); - background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77); - background-image: -o-linear-gradient(top, #226b9a, #1a4f77); - background-image: linear-gradient(to bottom, #226b9a, #1a4f77); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0); +.xv-grid-box .xv-grid-attr.emphasis { + color: #009000; } -.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr { - color: #fdfdfd; +.xv-grid-box .xv-grid-attr.warn { + color: #ff9c00; } -.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.placeholder { +.xv-grid-box .xv-grid-attr.italic { font-style: italic; - color: #99ccff; } -.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.hyperlink { - color: #ff6529; +.xv-grid-box .xv-grid-attr.placeholder { + font-style: italic; + color: #93a1a1; } -.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.header { - background: #99ccff; +.xv-grid-box .xv-grid-attr.hyperlink { + color: blue; } -.xv-list.xv-grid-list .xv-list-item .xv-list-column { - vertical-align: top; +.xv-grid-box .xv-gridbox-button { + color: #357ec7; + font-size: 18px; + border: none; + background: transparent; } -.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr { +.xv-grid-box .xv-grid-row { font-size: 12px; + background-color: #d8d8d8; + border-bottom: 1px solid #aaaaaa; + vertical-align: top; + /** + This is the grid header row + */ } -.xv-list.xv-grid-list .xv-list-item .xv-list-column.last { - border-right: none; +.xv-grid-box .xv-grid-row > * { + display: inline-block; } -.xv-list.xv-grid-list .xv-list-item .xv-list-column.name-column { - padding-left: 7px; +.xv-grid-box .xv-grid-row .xv-grid-header { + background-color: #d7d7d7; + color: #0e0e0e; + font-size: .8em; + font-weight: bold; + text-transform: uppercase; + padding-top: 4px; } -.xv-list.xv-grid-list .xv-list-item .xv-list-column.first { - padding-left: 7px; -} -.xv-list.xv-grid-list .xv-list-item .xv-list-column.second { - padding-left: 7px; -} -.xv-list.xv-grid-list .xv-list-item .xv-list-column.third { - padding-left: 7px; -} -.xv-list.xv-grid-list .xv-list-item .xv-list-column.short { - padding-left: 7px; -} -.xv-list.xv-grid-list .xv-list-item .xv-list-column.small { - padding-left: 7px; -} -.xv-list.xv-grid-list .xv-list-item .xv-list-column.medium { - padding-left: 7px; -} -.xv-list.xv-grid-list .xv-list-item .xv-list-column.descr { - padding-left: 7px; -} -.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr { - padding: 0px; -} -.xv-list-attr { - padding: 5px; - font-size: .8em; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - color: #070707; -} -.xv-list-attr.header { - padding: 4px; - background: #d8d8d8; - font-size: .7em; - font-weight: bold; - text-transform: uppercase; - color: #fdfdfd; -} -.xv-list-attr.footer { - padding: 4px; - background: #d8d8d8; - font-size: .7em; - font-weight: bold; - text-transform: uppercase; - color: #070707; -} -.xv-list-attr.right { - position: absolute; - right: 10px; -} -.xv-list-attr.text-align-right { - text-align: right; -} -.xv-list-attr.bold { - font-weight: bold; -} -.xv-list-attr.error { - color: #ff0000; -} -.xv-list-attr.emphasis { - color: #009000; -} -.xv-list-attr.warn { - color: #ff9c00; -} -.xv-list-attr.italic { - font-style: italic; -} -.xv-list-attr.placeholder { - font-style: italic; - color: #777777; -} -.xv-list-attr.hyperlink { - color: #357ec7; - cursor: pointer; -} -.xv-list-attr.disabled { - color: #777777; -} -/* Navigator */ -.xv-navigator-header { - font-size: small; - font-weight: bold; - text-transform: uppercase; - color: #ff6600; - padding-left: 20px; - border-bottom: 1px solid #0e0e0e; -} -.xv-workspace-header { - color: #fdfdfd; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - padding: 8px 0 0 8px; -} -/** - * Default ListItem styles when using a ModelDecorator. - */ -.xv-list .xv-model-decorator > .xv-list-item .xv-table { - display: table; - width: 100%; - table-layout: fixed; -} -.xv-list .xv-model-decorator > .xv-list-item .xv-table .xv-cell { - display: table-cell; -} -.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr { - /** - * Default styling for a model's id (as designated by 'idAttribute') - */ -} -.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-id { - color: #357ec7; - font-weight: bold; - cursor: pointer; -} -.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-name { - font-weight: bold; -} -.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-number { - text-align: right; -} -.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-money { - text-align: right; -} -.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-date { - text-align: right; -} -.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr { - color: white; -} -.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr.xm-attribute-id { - color: #ff6529; -} -/** - Styles related to pickers, combo boxes, and relation widgets -*/ -.onyx-picker-decorator .onyx-button { - padding: 12px 8px 12px 8px; - width: 150px; -} -.onyx-picker .onyx-menu-item { - text-align: left; - text-overflow: ellipsis; -} -.picker-icon { - position: absolute; - right: 0; - margin: 0 10px 0 2px; - color: #070707; -} -.xv-picker-button { - text-align: left; -} -.xv-picker-button .picker-content { - max-width: 100px; - overflow: hidden; -} -.xv-picker-button.disabled { - color: #777777; -} -.xv-picker-label { - color: #070707; - padding: 20px 8px 8px 8px; - text-align: right; - width: 130px; -} -.xv-picker-label.disabled { - color: #777777; -} -.xv-combobox-note { - padding: 14px 3px 8px 3px; - text-align: left; -} -/* - Styles relating to the grid box -*/ -/* Entire box including the grid and the summary panel */ -.xv-grid-box { - /** - This is the most general grid row that - is not specific to read-only or selected - */ -} -.xv-grid-box.small-panel { - width: 600px; -} -.xv-grid-box.medium-panel { - width: 700px; -} -.xv-grid-box.large-panel { - width: 800px; -} -.xv-grid-box .enyo-list-page > *:first-child .xv-grid-row { - border-top: 0; -} -.xv-grid-box .xv-above-grid-list { - border: 0; -} -.xv-grid-box .xv-scroller { - background: #f8f8f8; -} -.xv-limit-description .xv-grid-box .xv-grid-attr.bold { - font-weight: bold; -} -.xv-grid-box .xv-grid-attr.error { - color: #ff0000; -} -.xv-grid-box .xv-grid-attr.emphasis { - color: #009000; -} -.xv-grid-box .xv-grid-attr.warn { - color: #ff9c00; -} -.xv-grid-box .xv-grid-attr.italic { - font-style: italic; -} -.xv-grid-box .xv-grid-attr.placeholder { - font-style: italic; - color: #93a1a1; -} -.xv-grid-box .xv-grid-attr.hyperlink { - color: blue; -} -.xv-grid-box .xv-gridbox-button { - color: #357ec7; - font-size: 18px; - border: none; - background: transparent; -} -.xv-grid-box .xv-grid-row { - font-size: 12px; - background-color: #d8d8d8; - border-bottom: 1px solid #aaaaaa; - vertical-align: top; - /** - This is the grid header row - */ -} -.xv-grid-box .xv-grid-row > * { - display: inline-block; -} -.xv-grid-box .xv-grid-row .xv-grid-header { - background-color: #d7d7d7; - color: #0e0e0e; - font-size: .8em; - font-weight: bold; - text-transform: uppercase; - padding-top: 4px; -} -.xv-grid-box .xv-grid-row .xv-grid-header.last { - border-right: none; +.xv-grid-box .xv-grid-row .xv-grid-header.last { + border-right: none; } .xv-grid-box .xv-grid-row > * { padding: 6px 4px; @@ -2960,6 +2687,281 @@ a, text-align: center; font-size: 24px; } +/** + Styles relating to Lists +*/ +.xv-list-header { + background-color: #d8d8d8; + color: #fdfdfd; + font-size: .6em; + font-weight: bold; + text-transform: uppercase; + padding-top: 4px; + padding-bottom: 4px; + border-bottom: 1px solid #aaaaaa; +} +.xv-list-header .xv-list-column.last { + border-right: none; +} +.xv-list-header .xv-list-column.name-column, +.xv-list-header .xv-list-column.first, +.xv-list-header .xv-list-column.second, +.xv-list-header .xv-list-column.third, +.xv-list-header .xv-list-column.short, +.xv-list-header .xv-list-column.small, +.xv-list-header .xv-list-column.medium, +.xv-list-header .xv-list-column.descr { + padding-left: 7px; +} +/* List */ +.xv-list-column.line-number { + width: 30px; + text-align: right; +} +.xv-list-column.name-column { + width: 200px; +} +.xv-list-column.right-column { + width: 100px; + text-align: right; +} +.xv-list-column.short { + width: 100px; +} +.xv-list-column.small { + width: 125px; +} +.xv-list-column.medium { + width: 150px; +} +.xv-list-column.first { + width: 300px; +} +.xv-list-column.second { + width: 200px; +} +.xv-list-column.third { + width: 100px; +} +.xv-list-column.money, +.xv-list-column.quantity { + width: 75px; + text-align: right; +} +.xv-list-column.descr { + width: 200px; +} +.xv-list-column.icon { + width: 10px; +} +.xv-list { + background: #f8f8f8; +} +.xv-list .xv-list-item > * { + display: inline-block; + vertical-align: middle; +} +.xv-list .xv-list-item { + background-color: #fdfdfd; + border-bottom: 1px solid #d7d7d7; + min-height: 32px; +} +.xv-list .xv-list-item.header { + padding-top: 0; +} +.xv-list .xv-list-item.inactive { + background-color: #d8d8d8; + color: #070707; +} +.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr { + background: transparent; +} +.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr.placeholder { + color: #d8d8d8; +} +.xv-list .xv-list-item .xv-list-column .list-icon { + padding: 2px; + color: #666666; + vertical-align: sub; + border: 1px solid #efefef; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +} +.xv-list .xv-list-item.item-selected { + background: #226b9a; + background-color: #1f608c; + background-image: -moz-linear-gradient(top, #226b9a, #1a4f77); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77)); + background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77); + background-image: -o-linear-gradient(top, #226b9a, #1a4f77); + background-image: linear-gradient(to bottom, #226b9a, #1a4f77); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0); +} +.xv-list .xv-list-item.item-selected .xv-list-attr { + color: #fdfdfd; +} +.xv-list .xv-list-item.item-selected .xv-list-attr.placeholder { + font-style: italic; + color: #99ccff; +} +.xv-list .xv-list-item.item-selected .xv-list-attr.hyperlink { + color: #ff6529; +} +.xv-list .xv-list-item.item-selected .xv-list-attr.header { + background: #99ccff; +} +.xv-list .xv-list-item .xv-list-item-gear { + position: absolute; + right: 0px; + z-index: 999; +} +.xv-list.xv-grid-list { + background: #f8f8f8; +} +.xv-list.xv-grid-list .xv-list-item > * { + vertical-align: top; +} +.xv-list.xv-grid-list .xv-list-item { + padding-top: 7px !important; + padding-bottom: 9px !important; + border-bottom: 1px solid #aaaaaa !important; + background: #f8f8f8; +} +.xv-list.xv-grid-list .xv-list-item.item-selected { + background: #226b9a; + background-color: #1f608c; + background-image: -moz-linear-gradient(top, #226b9a, #1a4f77); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77)); + background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77); + background-image: -o-linear-gradient(top, #226b9a, #1a4f77); + background-image: linear-gradient(to bottom, #226b9a, #1a4f77); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0); +} +.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr { + color: #fdfdfd; +} +.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.placeholder { + font-style: italic; + color: #99ccff; +} +.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.hyperlink { + color: #ff6529; +} +.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.header { + background: #99ccff; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column { + vertical-align: top; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr { + font-size: 12px; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column.last { + border-right: none; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column.name-column { + padding-left: 7px; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column.first { + padding-left: 7px; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column.second { + padding-left: 7px; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column.third { + padding-left: 7px; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column.short { + padding-left: 7px; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column.small { + padding-left: 7px; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column.medium { + padding-left: 7px; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column.descr { + padding-left: 7px; +} +.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr { + padding: 0px; +} +.xv-list-attr { + padding: 5px; + font-size: .8em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + color: #070707; +} +.xv-list-attr.header { + padding: 4px; + background: #d8d8d8; + font-size: .7em; + font-weight: bold; + text-transform: uppercase; + color: #fdfdfd; +} +.xv-list-attr.footer { + padding: 4px; + background: #d8d8d8; + font-size: .7em; + font-weight: bold; + text-transform: uppercase; + color: #070707; +} +.xv-list-attr.right { + position: absolute; + right: 10px; +} +.xv-list-attr.text-align-right { + text-align: right; +} +.xv-list-attr.bold { + font-weight: bold; +} +.xv-list-attr.error { + color: #ff0000; +} +.xv-list-attr.emphasis { + color: #009000; +} +.xv-list-attr.warn { + color: #ff9c00; +} +.xv-list-attr.italic { + font-style: italic; +} +.xv-list-attr.placeholder { + font-style: italic; + color: #777777; +} +.xv-list-attr.hyperlink { + color: #357ec7; + cursor: pointer; +} +.xv-list-attr.disabled { + color: #777777; +} +/* Navigator */ +.xv-navigator-header { + font-size: small; + font-weight: bold; + text-transform: uppercase; + color: #ff6600; + padding-left: 20px; + border-bottom: 1px solid #0e0e0e; +} +.xv-workspace-header { + color: #fdfdfd; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding: 8px 0 0 8px; +} /** Styles relating to widgets in the pullout */ diff --git a/lib/enyo-x/source/views/module_container.js b/lib/enyo-x/source/views/module_container.js index e7ccd5edc..7130a80c2 100644 --- a/lib/enyo-x/source/views/module_container.js +++ b/lib/enyo-x/source/views/module_container.js @@ -38,19 +38,20 @@ trailing:true, white:true*/ {name: "startupProgressBar", kind: "onyx.ProgressBar", classes: "xv-startup-progress onyx-progress-button", progress: 0} ]}, - {kind: "onyx.Popup", name: "notifyPopup", centered: true, + {kind: "onyx.Popup", name: "notifyPopup", classes: "xv-popup", centered: true, onHide: "notifyHidden", modal: true, floating: true, scrim: true, components: [ - {name: "notifyMessage"}, - {tag: "br"}, - {kind: "onyx.Button", content: "_ok".loc(), name: "notifyOk", ontap: "notifyTap", - classes: "xv-popup-button", showing: false}, - {kind: "onyx.Button", content: "_yes".loc(), name: "notifyYes", ontap: "notifyTap", - classes: "xv-popup-button", showing: false}, - {kind: "onyx.Button", content: "_no".loc(), name: "notifyNo", ontap: "notifyTap", - classes: "xv-popup-button", showing: false}, - {kind: "onyx.Button", content: "_cancel".loc(), name: "notifyCancel", ontap: "notifyTap", - classes: "xv-popup-button", showing: false} + {name: "notifyMessage", classes: "message"}, + {classes: "xv-buttons", name: "notifyButtons", components: [ + {kind: "onyx.Button", content: "_ok".loc(), name: "notifyOk", ontap: "notifyTap", + showing: false, classes: "text"}, + {kind: "onyx.Button", content: "_yes".loc(), name: "notifyYes", ontap: "notifyTap", + showing: false, classes: "text"}, + {kind: "onyx.Button", content: "_no".loc(), name: "notifyNo", ontap: "notifyTap", + showing: false, classes: "text"}, + {kind: "onyx.Button", content: "_cancel".loc(), name: "notifyCancel", ontap: "notifyTap", + showing: false, classes: "text"} + ]} ]}, {kind: "onyx.Popup", name: "popupWorkspace", classes: "xv-popup xv-groupbox-popup", centered: true, autoDismiss: false, modal: true, floating: true, scrim: true}, @@ -59,7 +60,8 @@ trailing:true, white:true*/ resizeHandler: function () { this.inherited(arguments); if (this.$.notifyPopup.showing) { - this.$.notifyPopup.applyStyle("opacity", 1); // XXX not sure why this hack is necessary. + // This is a fix for an enyo bug that renders the popup as clear + this.$.notifyPopup.applyStyle("opacity", 1); } }, activate: function () { @@ -178,9 +180,7 @@ trailing:true, white:true*/ return this.$.navigator; }, getNotifyButtons: function () { - return _.filter(this.$, function (control) { - return control.name.substring(0, 6) === 'notify' && control.kind === 'onyx.Button'; - }); + return this.$.notifyButtons.controls; }, getStartupProgressBar: function () { return this.$.startupProgressBar; @@ -258,19 +258,10 @@ trailing:true, white:true*/ inEvent.type = inEvent.type || XM.Model.NOTICE; // show the appropriate buttons - _.each(this.$.notifyPopup.children, function (component) { - if (component.kind !== "onyx.Button") { - // not a button: do nothing. - } else if (_.indexOf(typeToButtonMap[String(inEvent.type)], component.name) >= 0) { - // in the show-me array, so show - component.setShowing(true); - } else { - // not in the show-me array, so hide - component.setShowing(false); - } + _.each(this.getNotifyButtons(), function (component) { + component.setShowing(_.indexOf(typeToButtonMap[String(inEvent.type)], component.name) >= 0); }); - // allow custom button text this.$.notifyYes.setContent(inEvent.yesLabel || "_yes".loc()); this.$.notifyNo.setContent(inEvent.noLabel || "_no".loc()); @@ -281,7 +272,7 @@ trailing:true, white:true*/ // it's the OK button unless it's a 2- or 3- way question, in which case it's YES this._activeNotify = inEvent.type === XM.Model.QUESTION || inEvent.type === XM.Model.YES_NO_CANCEL ? 1 : 0; _.each(this.getNotifyButtons(), function (button, index) { - button.addRemoveClass("onyx-blue", index === that._activeNotify); + button.addRemoveClass("selected", index === that._activeNotify); }); // delete out any previously added customComponents/customComponentControls @@ -302,9 +293,9 @@ trailing:true, white:true*/ // Add the custom component if (inEvent.component) { inEvent.component.name = "customComponent"; - inEvent.component.addBefore = this.$.notifyOk; + // can add styling class here instead of inline css + inEvent.component.addBefore = this.$.notifyButtons; this.$.notifyPopup.createComponent(inEvent.component); - this.$.notifyPopup.$.customComponent.addStyles("color:black;"); if (inEvent.componentModel) { this.$.notifyPopup.$.customComponent.setValue(inEvent.componentModel); } @@ -313,7 +304,8 @@ trailing:true, white:true*/ this._notifyDone = false; this.$.notifyPopup.render(); this.$.notifyPopup.show(); - this.$.notifyPopup.applyStyle("opacity", 1); // XXX not sure why this hack is necessary. + // Without this fix, the popup renders transparent + this.$.notifyPopup.applyStyle("opacity", 1); }, notifyHidden: function () { if (!this._notifyDone) { @@ -331,7 +323,7 @@ trailing:true, white:true*/ } else if (keyCode === 37 || (keyCode === 9 && isShift)) { // left or shift-tab - notifyButtons[activeIndex].removeClass("onyx-blue"); + notifyButtons[activeIndex].removeClass("selected"); for (nextShowing = activeIndex - 1; nextShowing >= 0; nextShowing--) { if (nextShowing === 0 && !notifyButtons[nextShowing].showing) { // there are no showing buttons to the left @@ -346,11 +338,11 @@ trailing:true, white:true*/ activeIndex = nextShowing; } this._activeNotify = activeIndex; - notifyButtons[activeIndex].addClass("onyx-blue"); + notifyButtons[activeIndex].addClass("selected"); } else if (keyCode === 39 || keyCode === 9) { // right or tab - notifyButtons[activeIndex].removeClass("onyx-blue"); + notifyButtons[activeIndex].removeClass("selected"); for (nextShowing = activeIndex + 1; nextShowing < notifyButtons.length; nextShowing++) { if (nextShowing + 1 === notifyButtons.length && !notifyButtons[nextShowing].showing) { // there are no showing buttons to the right @@ -366,7 +358,7 @@ trailing:true, white:true*/ } this._activeNotify = activeIndex; - notifyButtons[activeIndex].addClass("onyx-blue"); + notifyButtons[activeIndex].addClass("selected"); } }, /** @@ -447,27 +439,31 @@ trailing:true, white:true*/ maxHeight: "400px", horizontal: "hidden" }, {owner: this}); - this.$.popupWorkspace.createComponent({name: "workspace", kind: inEvent.workspace, container: this.$.popupScroller}); + this.$.popupWorkspace.createComponent({name: "workspace", kind: inEvent.workspace, + container: this.$.popupScroller}); + // TODO: inline css - git rid of it! this.$.popupWorkspace.$.workspace.addStyles("color:black;"); this.$.popupWorkspace.$.workspace.setValue(inEvent.model); - this.$.popupWorkspace.createComponent({ + // create button bar + this.$.popupWorkspace.createComponent({classes: "xv-buttons", name: "workspaceButtons"}, {owner: this}); + this.$.workspaceButtons.createComponents([{ kind: "onyx.Button", content: "_save".loc(), name: "popupWorkspaceSave", ontap: "popupWorkspaceTap", - classes: "onyx-blue xv-popup-button" - }, {owner: this}); - this.$.popupWorkspace.createComponent({ + classes: "selected text" + }, + { kind: "onyx.Button", content: "_cancel".loc(), name: "popupWorkspaceCancel", ontap: "popupWorkspaceTap", - classes: "xv-popup-button" - }, {owner: this}); - + classes: "text" + }], {owner: this}); this.$.popupWorkspace.render(); this.$.popupWorkspace.show(); - this.$.popupWorkspace.applyStyle("opacity", 1); // XXX not sure why this hack is necessary. + // Without this fix, the popup renders transparent + this.$.popupWorkspace.applyStyle("opacity", 1); }, popupWorkspaceTap: function (inSender, inEvent) { var model = this.$.popupWorkspace.$.workspace.value, diff --git a/node-datasource/routes/app.js b/node-datasource/routes/app.js index e083ee824..4ddcdd67c 100644 --- a/node-datasource/routes/app.js +++ b/node-datasource/routes/app.js @@ -103,6 +103,15 @@ var async = require("async"), }, fetchSuccess = function (model, result) { var sendExtensions = function (res, extensions) { + var filteredExtensions; + if (req.query.extensions) { + // the user is requesting to only see a certain set of extensions + filteredExtensions = JSON.parse(req.query.extensions); + extensions = extensions.filter(function (ext) { + return _.contains(filteredExtensions, ext.name); + }); + } + extensions.sort(function (ext1, ext2) { if (ext1.loadOrder !== ext2.loadOrder) { return ext1.loadOrder - ext2.loadOrder; diff --git a/node-datasource/routes/auth.js b/node-datasource/routes/auth.js index 28e550429..fea2dc7bd 100644 --- a/node-datasource/routes/auth.js +++ b/node-datasource/routes/auth.js @@ -21,6 +21,9 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */ 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) { + if (req.body.extensions) { + pathName = pathName + "?extensions=" + req.body.extensions; + } if (req.body.hash && req.body.hash.charAt(0) === "#") { pathName = pathName + req.body.hash; } diff --git a/node-datasource/routes/generate_oauth_key.js b/node-datasource/routes/generate_oauth_key.js index b4c69d571..16858d815 100644 --- a/node-datasource/routes/generate_oauth_key.js +++ b/node-datasource/routes/generate_oauth_key.js @@ -7,8 +7,7 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */ (function () { "use strict"; - var ursa = require("ursa"), - exec = require("child_process").exec, + var exec = require("child_process").exec, forge = require("node-forge"), spawn = require("child_process").spawn, async = require("async"), @@ -29,10 +28,7 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */ res.send({isError: true, error: err}); }, genKey = function (model, result) { - /** - * This is REALLY slow in pure javascript. ursa is much faster. - * @See: https://github.com/digitalbazaar/forge/issues/125 - forge.pki.rsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) { + forge.pki.rsa.generateKeyPair({bits: 2048, workers: -1}, function (err, keypair) { if (err) { res.send({isError: true, message: "Error generating keypair: " + err.message, error: err}); return; @@ -40,16 +36,6 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */ fetchSuccess(model, result, keypair); }); - */ - - // Use ursa for the key gen and then convert to forge's format. - var keypair = ursa.generatePrivateKey(); - var keys = { - privateKey: forge.pki.privateKeyFromPem(keypair.toPrivatePem().toString()), - publicKey: forge.pki.publicKeyFromPem(keypair.toPublicPem().toString()) - }; - - fetchSuccess(model, result, keys); }, sendP12 = function (keys) { // It's possible and much easier to generate the p12 file without a diff --git a/node-datasource/xt/xt.js b/node-datasource/xt/xt.js index f00146aff..6e28736e5 100644 --- a/node-datasource/xt/xt.js +++ b/node-datasource/xt/xt.js @@ -113,9 +113,5 @@ XT = { }; // give any running process the opportunity to save state // or log as gracefully as possible process.once('exit', _.bind(X.cleanup, X)); - - _.forEach(["SIGINT", "SIGHUP", "SIGQUIT", "SIGKILL", "SIGSEGV", "SIGILL"], function (sig) { - process.once(sig, _.bind(sighandler, X, sig)); - }); }); }()); diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 8feddecf5..37627091e 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1856,10 +1856,6 @@ "version": "2.3.3", "from": "underscore.string@~2.3.3" }, - "ursa": { - "version": "0.8.0", - "from": "ursa@0.8.x" - }, "winston": { "version": "0.7.3", "from": "winston@0.7.x", @@ -1967,7 +1963,7 @@ } }, "xtuple-linguist": { - "version": "0.1.0", + "version": "0.1.1", "from": "xtuple-linguist@0.1.x" }, "xtuple-query": { diff --git a/package.json b/package.json index 69a85da66..88d940fdc 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "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" }, @@ -61,7 +60,7 @@ "googleapis": "~0.4.6" }, "engines": { - "node": "0.8.x" + "node": "^0.10" }, "main": "node-datasource/main.js", "scripts": { diff --git a/scripts/install_xtuple.sh b/scripts/install_xtuple.sh index 046c1b236..ee2121be9 100644 --- a/scripts/install_xtuple.sh +++ b/scripts/install_xtuple.sh @@ -23,7 +23,7 @@ sudo apt-get -q -y install \ python-software-properties \ software-properties-common -NODE_VERSION=0.8.26 +NODE_VERSION=0.10.31 DEBDIST=`lsb_release -c -s` echo "Trying to install xTuple for platform ${DEBDIST}" diff --git a/scripts/lib/build_database.js b/scripts/lib/build_database.js index 6f646955c..aa0b85c58 100644 --- a/scripts/lib/build_database.js +++ b/scripts/lib/build_database.js @@ -89,7 +89,8 @@ var async = require('async'), baseName.indexOf('distribution') >= 0, registerExtension: isExtension, runJsInit: !isFoundation && !isLibOrm, - wipeViews: isApplicationCore && spec.wipeViews, + wipeViews: isFoundation && spec.wipeViews, + wipeOrms: isApplicationCore && spec.wipeViews, extensionLocation: isCoreExtension ? "/core-extensions" : isPublicExtension ? "/xtuple-extensions" : isPrivateExtension ? "/private-extensions" : diff --git a/scripts/lib/util/init_database.js b/scripts/lib/util/init_database.js index 4dca75c8e..3794cfb7b 100644 --- a/scripts/lib/util/init_database.js +++ b/scripts/lib/util/init_database.js @@ -6,7 +6,7 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */ "use strict"; var async = require("async"), - exec = require('child_process').exec, + proc = require('child_process'), path = require('path'), os = require('os'), winston = require('winston'), @@ -35,21 +35,29 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */ var schemaPath = path.join(path.dirname(spec.source), "440_schema.sql"); winston.info("Building schema for database " + databaseName); - exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " + - creds.port + " -d " + databaseName + " -f " + schemaPath, - {maxBuffer: 40000 * 1024 /* 200x default */}, done); + var process = proc.spawn('psql', [ + '-q', '-U', creds.username, '-h', creds.hostname, '--single-transaction', '-p', + creds.port, '-d', databaseName, '-f', schemaPath + ], { stdio: 'inherit' }); + process.on('exit', done); + }, populateData = function (done) { winston.info("Populating data for database " + databaseName + " from " + spec.source); - exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " + - creds.port + " -d " + databaseName + " -f " + spec.source, - {maxBuffer: 40000 * 1024 /* 200x default */}, done); + var process = proc.spawn('psql', [ + '-q', '-U', creds.username, '-h', creds.hostname, '--single-transaction', '-p', + creds.port, '-d', databaseName, '-f', spec.source + ], { stdio: 'inherit'}); + process.on('exit', done); }, // use exec to restore the backup. The alternative, reading the backup file into a string to query // doesn't work because the backup file is binary. restoreBackup = function (done) { - exec("pg_restore -U " + creds.username + " -h " + creds.hostname + " -p " + - creds.port + " -d " + databaseName + " -j " + os.cpus().length + " " + spec.backup, function (err, res) { + var process = proc.spawn('pg_restore', [ + '-U', creds.username, '-h', creds.hostname, '-p', creds.port, '-d', databaseName, + '-j', os.cpus().length, spec.backup + ], { stdio: 'inherit' }); + process.on('exit', function (err, res) { if (err) { console.log("ignoring restore db error", err); } diff --git a/scripts/lib/util/process_manifest.js b/scripts/lib/util/process_manifest.js index 90f60306f..44ed46a9d 100644 --- a/scripts/lib/util/process_manifest.js +++ b/scripts/lib/util/process_manifest.js @@ -56,6 +56,19 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */ } 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/wipe_views.sql"), + function (err, wipeSql) { + if (err) { + callback(err); + return; + } + extensionSql = wipeSql + extensionSql; + callback(null, extensionSql); + }); + + } else if (options.wipeOrms) { // 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"), diff --git a/test/extensions/all/configure.js b/test/extensions/all/configure.js index 112483360..e387b7e70 100644 --- a/test/extensions/all/configure.js +++ b/test/extensions/all/configure.js @@ -14,14 +14,14 @@ 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; diff --git a/test/extensions/all/workspace.js b/test/extensions/all/workspace.js index a31a8869b..2ad8ad463 100644 --- a/test/extensions/all/workspace.js +++ b/test/extensions/all/workspace.js @@ -16,7 +16,7 @@ assert = require("chai").assert; describe('Workspaces', function () { - this.timeout(20 * 1000); + this.timeout(60 * 1000); it('should log in first', function (done) { zombieAuth.loadApp(done); }); @@ -83,7 +83,7 @@ var workspaceContainer, workspace, model, id, moduleContainer; beforeEach(function (done) { - this.timeout(10 * 1000); + this.timeout(60 * 1000); smoke.navigateToExistingWorkspace(XT.app, "XV.ClassCodeList", function (_workspaceContainer) { workspaceContainer = _workspaceContainer; @@ -101,7 +101,7 @@ }); }); afterEach(function (done) { - this.timeout(10 * 1000); + this.timeout(60 * 1000); // maybe one of the tests already released the lock if (!model.hasLockKey()) { diff --git a/test/extensions/crm/characteristics.js b/test/extensions/crm/characteristics.js index cf880fc15..71f410cfa 100644 --- a/test/extensions/crm/characteristics.js +++ b/test/extensions/crm/characteristics.js @@ -199,7 +199,7 @@ }); afterEach(function (done) { - this.timeout(10 * 1000); + this.timeout(30 * 1000); // restore permissions _.extend(XT.session.privileges.attributes, originalPrivileges); diff --git a/test/extensions/sales/sales_order_workspace.js b/test/extensions/sales/sales_order_workspace.js index 3f1548e0b..43406d36e 100644 --- a/test/extensions/sales/sales_order_workspace.js +++ b/test/extensions/sales/sales_order_workspace.js @@ -44,7 +44,8 @@ }); }; - describe('Sales Order Workspace', function () { + // TODO: move to sales order spec + describe.skip('Sales Order Workspace', function () { this.timeout(30 * 1000); // @@ -142,7 +143,7 @@ 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(), @@ -150,7 +151,7 @@ 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 () { @@ -160,7 +161,7 @@ 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; } diff --git a/test/lib/crud.js b/test/lib/crud.js index e3c47048a..7f95c0052 100644 --- a/test/lib/crud.js +++ b/test/lib/crud.js @@ -366,7 +366,7 @@ var _ = require("underscore"), // Step 1: load the environment with Zombie // it('can be loaded with a zombie session', function (done) { - this.timeout(40 * 1000); + this.timeout(60 * 1000); zombieAuth.loadApp({callback: done, verbose: data.verbose, loginDataPath: data.loginDataPath}); }); @@ -383,7 +383,7 @@ var _ = require("underscore"), // Step 3: initialize the model to get the ID from the database // it('can be initialized by fetching an id from the server', function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); init(data, done); }); @@ -392,13 +392,13 @@ var _ = require("underscore"), // _.each(data.beforeSetActions || [], function (spec) { it(spec.it, function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); spec.action(data, done); }); }); it('can have its values set', function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); data.updated = false; setModel(data, done); }); @@ -406,14 +406,14 @@ var _ = require("underscore"), // if this model has comments, set them on the model if (data.commentType) { it('can have its comments set', function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); setComments(data, done); }); } _.each(data.beforeSaveActions || [], function (spec) { it(spec.it, function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); spec.action(data, done); }); }); @@ -423,12 +423,12 @@ var _ = require("underscore"), // if (!data.skipSave) { it('can be saved to the database', function (done) { - this.timeout(10 * 1000); + this.timeout(60 * 1000); save(data, done); }); _.each(data.afterSaveActions || [], function (spec) { it(spec.it, function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); spec.action(data, done); }); }); @@ -446,7 +446,7 @@ var _ = require("underscore"), // Step 7: save the updated model to the database // it('can be re-saved to the database', function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); save(data, done); }); } @@ -456,21 +456,21 @@ var _ = require("underscore"), // _.each(data.beforeDeleteActions || [], function (spec) { it(spec.it, function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); spec.action(data, done); }); }); if (!data.skipDelete) { it('can be deleted from the database', function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); destroy(data, done); }); } _.each(data.afterDeleteActions || [], function (spec) { it(spec.it, function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); spec.action(data, done); }); }); diff --git a/test/lib/smoke.js b/test/lib/smoke.js index 76af701ff..166299454 100644 --- a/test/lib/smoke.js +++ b/test/lib/smoke.js @@ -224,7 +224,7 @@ 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, @@ -257,7 +257,7 @@ var workspaceContainer, workspace; it('can get to a new workspace', function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); navigateToNewWorkspace(XT.app, spec.listKind, function (_workspaceContainer) { workspaceContainer = _workspaceContainer; done(); @@ -270,12 +270,12 @@ }); _.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; @@ -284,7 +284,7 @@ }); _.each(spec.afterSaveUIActions || [], function (spec) { it(spec.it, function (done) { - this.timeout(20 * 1000); + this.timeout(60 * 1000); spec.action(workspace, done); }); }); @@ -292,7 +292,7 @@ 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); }); }; diff --git a/test/lib/zombie_auth.js b/test/lib/zombie_auth.js index a3b379098..579c60827 100644 --- a/test/lib/zombie_auth.js +++ b/test/lib/zombie_auth.js @@ -2,6 +2,35 @@ regexp:true, undef:true, strict:true, trailing:true, white:true */ /*global XT:true, XM:true, XV:true, XZ:true, enyo:true, XG:true */ +var _ = require('underscore'); +global.URL = require('url'); +var parse = global.URL.parse; +var resolve = global.URL.resolve; +global.URL.parse = function (url) { + "use strict"; + console.log('URL.parse', url); + if (_.isObject(url) && _.isString(url.href)) { + return parse(url.href); + } + else { + return parse(url); + } +}; +global.URL.resolve = function (from, to) { + "use strict"; + console.log('URL.resolve from', from); + console.log('URL.resolve to', to); + if (_.isObject(from)) { + from = from.href || '/'; + } + if (_.isObject(to)) { + to = to.href || ''; + } + + return resolve(from, to); +}; + + // global objects enyo = {}; XT = {}; @@ -10,9 +39,11 @@ XM = {}; XV = {}; XZ = {}; // xTuple Zombie. Used to help zombie within the context of these tests. +// https://github.com/mikeal/request/issues/418#issuecomment-17149236 +process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; + var assert = require('assert'), zombie = require('zombie'), - URL = require('url'), _ = require('underscore'); @@ -100,23 +131,15 @@ Simplest possible usage: return; } - var parse = URL.parse; - URL.parse = function (url) { - if (_.isObject(url) && _.isString(url.href)) { - return parse(url.href); - } - else { - return parse(url); - } - }; - zombie.visit(host, {debug: verboseMode}, function (e, browser) { + zombie.visit(host, {debug: verboseMode, runScripts: false}, function (e, browser) { if (e) { - //console.log("Zombie visit error: ", e); + console.log("Zombie visit error: ", e); } // // This is the login screen // + browser.runScripts = true; browser .fill('id', username) .fill('password', password) diff --git a/test/specs/invoice.js b/test/specs/invoice.js index e6740902b..0a43b8ec0 100644 --- a/test/specs/invoice.js +++ b/test/specs/invoice.js @@ -864,9 +864,9 @@ TODO deferred to later sprint: @description When currency or invoice date is changed outstanding credit should be recalculated. */ - it.skip("When currency or invoice date is changed outstanding credit should be recalculated", + it.("When currency or invoice date is changed outstanding credit should be recalculated", function (done) { - // frustratingly nondeterministic + this.timeout(9000); var outstandingCreditChanged = function () { if (invoiceModel.get("outstandingCredit")) {