language: node_js
node_js:
- - "0.8"
+ - "0.10"
install:
- "bash scripts/install_xtuple.sh -ipn"
XV.registerModelWorkspace("XM.UserAccountRoleRelation", "XV.UserAccountRoleWorkspace");
XV.registerModelWorkspace("XM.UserAccountRoleListItem", "XV.UserAccountRoleWorkspace");
-
}());
"_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",
-1,
NULL,
_fc.fincharg_markoninvoice,
- 'Finance Charge Assessment',
+-- - enhance data shown in the item description for the invoice line to indicate which invoice is affected
+-- - Feature Request 23344
+-- 'Finance Charge Assessment',
+ 'Finance Charge Assessment - Invoice Number ' || _ar.aropen_docnumber || ' - Past Due Balance ' || (_ar.aropen_amount - _ar.aropen_paid) || ' Due Date - ' || _ar.aropen_duedate,
1.0,
1.0,
pAssessAmount,
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
pQuheadid ALIAS FOR $1;
+ _qunumber TEXT;
+ _ponumber TEXT;
_soheadid INTEGER;
_soitemid INTEGER;
_orderid INTEGER;
RETURN -5;
END IF;
- IF ( (_usespos) AND (NOT _blanketpos) ) THEN
- PERFORM cohead_id
- FROM quhead JOIN cohead ON ( (cohead_cust_id=quhead_cust_id) AND
- (UPPER(cohead_custponumber)=UPPER(quhead_custponumber)) )
+ IF (_usespos) THEN
+ SELECT quhead_number, COALESCE(quhead_custponumber, ''), cohead_id INTO _qunumber, _ponumber, _soheadid
+ FROM quhead LEFT OUTER JOIN cohead ON ( (cohead_cust_id=quhead_cust_id) AND
+ (UPPER(cohead_custponumber)=UPPER(quhead_custponumber)) )
WHERE (quhead_id=pQuheadid);
- IF (FOUND) THEN
- RAISE EXCEPTION 'Duplicate Customer PO';
+ IF (_ponumber = '') THEN
+ RAISE EXCEPTION 'Customer PO required for Quote % [xtuple: convertQuote, -7, %]',
+ _qunumber, _qunumber;
+ END IF;
+
+ IF ( (NOT _blanketpos) AND (_soheadid IS NOT NULL) ) THEN
+ RAISE EXCEPTION 'Duplicate Customer PO % for Quote % [xtuple: convertQuote, -8, %, %]',
+ _ponumber, _qunumber,
+ _ponumber, _qunumber;
END IF;
END IF;
AND (comment_source_id=pQuheadid) );
FOR _r IN SELECT quitem.*,
- quhead_number, quhead_prj_id,
+ quhead_number, quhead_prj_id, quhead_saletype_id,
itemsite_item_id, itemsite_leadtime,
itemsite_createsopo, itemsite_createsopr,
item_type, COALESCE(quitem_itemsrc_id, itemsrc_id, -1) AS itemsrcid
IF (fetchMetricBool('enablextcommissionission')) THEN
PERFORM xtcommission.getSalesReps(quhead_cust_id, quhead_shipto_id,
- _r.itemsite_item_id, _r.quitem_price,
+ _r.itemsite_item_id, _r.quhead_saletype_id,
+ _r.quitem_price, _r.quitem_custprice,
_soitemid, 'SalesItem')
FROM quhead
WHERE (quhead_id=pQuheadid);
IF (_r.quitem_createorder) THEN
IF (_r.item_type IN ('M')) THEN
- SELECT createWo( CAST(_r.quhead_number AS INTEGER), supply.itemsite_id, 1, (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
- _r.itemsite_leadtime, _r.quitem_scheddate, _r.quitem_memo, 'S', _soitemid, _r.quhead_prj_id ) INTO _orderId
+ SELECT createWo( CAST(_soNum AS INTEGER), supply.itemsite_id, 1,
+ (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
+ _r.itemsite_leadtime, _r.quitem_scheddate, _r.quitem_memo,
+ 'S', _soitemid, _r.quhead_prj_id ) INTO _orderId
FROM itemsite sold, itemsite supply
WHERE ((sold.itemsite_item_id=supply.itemsite_item_id)
AND (supply.itemsite_warehous_id=_r.quitem_order_warehous_id)
AND (charass_target_id=_r.quitem_id));
ELSIF ( (_r.item_type IN ('P', 'O')) AND (_r.itemsite_createsopr) ) THEN
- SELECT createPr( CAST(_r.quhead_number AS INTEGER), _r.quitem_itemsite_id, (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
+ SELECT createPr( CAST(_soNum AS INTEGER), _r.quitem_itemsite_id,
+ (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
_r.quitem_scheddate, '', 'S', _soitemid ) INTO _orderId;
_orderType := 'R';
UPDATE pr SET pr_prj_id=_r.quhead_prj_id WHERE pr_id=_orderId;
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
pQuheadid ALIAS FOR $1;
+ _qunumber TEXT;
+ _ponumber TEXT;
_iheadid INTEGER;
_iitemid INTEGER;
_orderid INTEGER;
END IF;
-- PO/blanket PO checks
+ IF (_usespos) THEN
+ SELECT quhead_number, COALESCE(quhead_custponumber, ''), invchead_id INTO _qunumber, _ponumber, _iheadid
+ FROM quhead LEFT OUTER JOIN invchead ON ( (invchead_cust_id=quhead_cust_id) AND
+ (UPPER(invchead_ponumber)=UPPER(quhead_custponumber)) )
+ WHERE (quhead_id=pQuheadid);
+ IF (_ponumber = '') THEN
+ RAISE EXCEPTION 'Customer PO required for Quote % [xtuple: convertQuote, -7, %]',
+ _qunumber, _qunumber;
+ END IF;
+
+ IF ( (NOT _blanketpos) AND (_iheadid IS NOT NULL) ) THEN
+ RAISE EXCEPTION 'Duplicate Customer PO % for Quote % [xtuple: convertQuote, -8, %, %]',
+ _ponumber, _qunumber,
+ _ponumber, _qunumber;
+ END IF;
+ END IF;
+
+ IF (_usespos) THEN
+ SELECT quhead_number INTO _qunumber
+ FROM quhead
+ WHERE (quhead_id=pQuheadid)
+ AND (COALESCE(quhead_custponumber, '') = '');
+ IF (FOUND) THEN
+ RAISE EXCEPTION 'Customer PO required for Quote % [xtuple: convertQuote, -7, %]',
+ _qunumber, _qunumber;
+ END IF;
+ END IF;
+
IF ( (_usespos) AND (NOT _blanketpos) ) THEN
- PERFORM invchead_id
+ SELECT quhead_number, quhead_custponumber INTO _qunumber, _ponumber
FROM quhead JOIN invchead ON ( (invchead_cust_id=quhead_cust_id) AND
- (UPPER(invchead_custponumber)=UPPER(quhead_custponumber)) )
+ (UPPER(invchead_ponumber)=UPPER(quhead_custponumber)) )
WHERE (quhead_id=pQuheadid);
IF (FOUND) THEN
- RAISE EXCEPTION 'Duplicate Customer PO';
+ RAISE EXCEPTION 'Duplicate Customer PO % for Quote % [xtuple: convertQuote, -8, %, %]',
+ _ponumber, _qunumber,
+ _ponumber, _qunumber;
END IF;
END IF;
-
+
--Check to see if an invoice exists with the quote number
PERFORM quhead_number, invchead_id
*/
FOR _r IN SELECT quitem.*,
- quhead_number, quhead_prj_id,
+ quhead_number, quhead_prj_id, quhead_saletype_id,
itemsite_item_id, itemsite_leadtime,
itemsite_createsopo, itemsite_createsopr,
item_type, COALESCE(quitem_itemsrc_id, itemsrc_id, -1) AS itemsrcid
IF (fetchMetricBool('enablextcommissionission')) THEN
PERFORM xtcommission.getSalesReps(quhead_cust_id, quhead_shipto_id,
- _r.itemsite_item_id, _r.quitem_price,
+ _r.itemsite_item_id, _r.quhead_saletype_id,
+ _r.quitem_price, _r.quitem_custprice,
_iitemid, 'InvoiceItem')
FROM quhead
WHERE (quhead_id=pQuheadid);
begin
if fetchMetricText('ServerVersion') < '4.7.0' then
update itemsite set itemsite_qtyonhand=(itemsite_qtyonhand + itemsite_nnqoh);
- alter table itemsite drop column itemsite_nnqoh;
+ alter table itemsite drop column itemsite_nnqoh cascade;
end if;
end$$;
\ No newline at end of file
(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)
BEGIN
-- Cache some information
- SELECT item_type INTO _r
+ -- Added item_number as part of feature request 21645
+ SELECT item_type, item_number INTO _r
FROM item
WHERE (item_id=NEW.itemsite_item_id);
END IF;
END IF;
+-- Added item_number to error messages displayed to fulfill Feature Request 21645
IF (NEW.itemsite_qtyonhand < 0 AND NEW.itemsite_costmethod = 'A') THEN
- RAISE EXCEPTION 'Itemsite (%) is set to use average costing and is not allowed to have a negative quantity on hand.', NEW.itemsite_id;
+ RAISE EXCEPTION 'Itemsite (%) is set to use average costing and is not allowed to have a negative quantity on hand.', 'ID: ' || NEW.itemsite_id || ', Item: ' || _r.item_number;
ELSIF (NEW.itemsite_value < 0 AND NEW.itemsite_costmethod = 'A') THEN
- RAISE EXCEPTION 'This transaction results in a negative itemsite value. Itemsite (%) is set to use average costing and is not allowed to have a negative value.', NEW.itemsite_id;
- END IF;
+ RAISE EXCEPTION 'This transaction results in a negative itemsite value. Itemsite (%) is set to use average costing and is not allowed to have a negative value.', 'ID: ' || NEW.itemsite_id || ', Item: ' || _r.item_number; END IF;
-- Handle the ChangeLog
IF ( SELECT (metric_value='t')
@defaultPanelWidth: 320px;
@toolbarHeight: 55px;
@searchLength: 185px;
+// popups
+@maxMessageHeight: 500px;
+@maxMessageWidth: 500px;
// libs
@import "../../lib/font-awesome/less/font-awesome.less";
*/
.xv-popup {
background: @header-gray;
- margin: 0;
- max-height: 400px;
- width: 400px;
min-width: @defaultPanelWidth;
- padding: 7px;
+ padding: 10px;
text-align: center;
+ .message {
+ margin-bottom: 10px;
+ max-height: @maxMessageHeight;
+ max-width: @maxMessageWidth;
+ }
+
&.xv-groupbox-popup {
.xv-workspace-container > .xv-workspace > .xv-workspace-panel;
color: @black;
*/
.xv-popup {
background: #505050;
- margin: 0;
- max-height: 400px;
- width: 400px;
min-width: 320px;
- padding: 7px;
+ padding: 10px;
text-align: center;
}
+.xv-popup .message {
+ margin-bottom: 10px;
+ max-height: 500px;
+ max-width: 500px;
+}
.xv-popup.xv-groupbox-popup {
width: 320px;
margin: 0 4px 0 2px;
border: none;
}
/**
- Styles relating to Lists
-*/
-.xv-list-header {
- background-color: #d8d8d8;
- color: #fdfdfd;
- font-size: .6em;
- font-weight: bold;
- text-transform: uppercase;
- padding-top: 4px;
- padding-bottom: 4px;
- border-bottom: 1px solid #aaaaaa;
+ * Default ListItem styles when using a ModelDecorator.
+ */
+.xv-list .xv-model-decorator > .xv-list-item .xv-table {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
}
-.xv-list-header .xv-list-column.last {
- border-right: none;
+.xv-list .xv-model-decorator > .xv-list-item .xv-table .xv-cell {
+ display: table-cell;
}
-.xv-list-header .xv-list-column.name-column,
-.xv-list-header .xv-list-column.first,
-.xv-list-header .xv-list-column.second,
-.xv-list-header .xv-list-column.third,
-.xv-list-header .xv-list-column.short,
-.xv-list-header .xv-list-column.small,
-.xv-list-header .xv-list-column.medium,
-.xv-list-header .xv-list-column.descr {
- padding-left: 7px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr {
+ /**
+ * Default styling for a model's id (as designated by 'idAttribute')
+ */
}
-/* List */
-.xv-list-column.line-number {
- width: 30px;
- text-align: right;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-id {
+ color: #357ec7;
+ font-weight: bold;
+ cursor: pointer;
}
-.xv-list-column.name-column {
- width: 200px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-name {
+ font-weight: bold;
}
-.xv-list-column.right-column {
- width: 100px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-number {
text-align: right;
}
-.xv-list-column.short {
- width: 100px;
-}
-.xv-list-column.small {
- width: 125px;
-}
-.xv-list-column.medium {
- width: 150px;
-}
-.xv-list-column.first {
- width: 300px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-money {
+ text-align: right;
}
-.xv-list-column.second {
- width: 200px;
+.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-date {
+ text-align: right;
}
-.xv-list-column.third {
- width: 100px;
+.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr {
+ color: white;
}
-.xv-list-column.money,
-.xv-list-column.quantity {
- width: 75px;
- text-align: right;
+.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr.xm-attribute-id {
+ color: #ff6529;
}
-.xv-list-column.descr {
- width: 200px;
+/**
+ Styles related to pickers, combo boxes, and relation widgets
+*/
+.onyx-picker-decorator .onyx-button {
+ padding: 12px 8px 12px 8px;
+ width: 150px;
}
-.xv-list-column.icon {
- width: 10px;
+.onyx-picker .onyx-menu-item {
+ text-align: left;
+ text-overflow: ellipsis;
}
-.xv-list {
- background: #f8f8f8;
+.picker-icon {
+ position: absolute;
+ right: 0;
+ margin: 0 10px 0 2px;
+ color: #070707;
}
-.xv-list .xv-list-item > * {
- display: inline-block;
- vertical-align: middle;
+.xv-picker-button {
+ text-align: left;
}
-.xv-list .xv-list-item {
- background-color: #fdfdfd;
- border-bottom: 1px solid #d7d7d7;
- min-height: 32px;
+.xv-picker-button .picker-content {
+ max-width: 100px;
+ overflow: hidden;
}
-.xv-list .xv-list-item.header {
- padding-top: 0;
+.xv-picker-button.disabled {
+ color: #777777;
}
-.xv-list .xv-list-item.inactive {
- background-color: #d8d8d8;
+.xv-picker-label {
color: #070707;
+ padding: 20px 8px 8px 8px;
+ text-align: right;
+ width: 130px;
}
-.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr {
- background: transparent;
-}
-.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr.placeholder {
- color: #d8d8d8;
+.xv-picker-label.disabled {
+ color: #777777;
}
-.xv-list .xv-list-item .xv-list-column .list-icon {
- padding: 2px;
- color: #666666;
- vertical-align: sub;
- border: 1px solid #efefef;
- -webkit-border-radius: 2px;
- -moz-border-radius: 2px;
- border-radius: 2px;
+.xv-combobox-note {
+ padding: 14px 3px 8px 3px;
+ text-align: left;
}
-.xv-list .xv-list-item.item-selected {
- background: #226b9a;
- background-color: #1f608c;
- background-image: -moz-linear-gradient(top, #226b9a, #1a4f77);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77));
- background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77);
- background-image: -o-linear-gradient(top, #226b9a, #1a4f77);
- background-image: linear-gradient(to bottom, #226b9a, #1a4f77);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0);
+/*
+ Styles relating to the grid box
+*/
+/* Entire box including the grid and the summary panel */
+.xv-grid-box {
+ /**
+ This is the most general grid row that
+ is not specific to read-only or selected
+ */
}
-.xv-list .xv-list-item.item-selected .xv-list-attr {
- color: #fdfdfd;
+.xv-grid-box.small-panel {
+ width: 600px;
}
-.xv-list .xv-list-item.item-selected .xv-list-attr.placeholder {
- font-style: italic;
- color: #99ccff;
+.xv-grid-box.medium-panel {
+ width: 700px;
}
-.xv-list .xv-list-item.item-selected .xv-list-attr.hyperlink {
- color: #ff6529;
+.xv-grid-box.large-panel {
+ width: 800px;
}
-.xv-list .xv-list-item.item-selected .xv-list-attr.header {
- background: #99ccff;
+.xv-grid-box .enyo-list-page > *:first-child .xv-grid-row {
+ border-top: 0;
}
-.xv-list .xv-list-item .xv-list-item-gear {
- position: absolute;
- right: 0px;
- z-index: 999;
+.xv-grid-box .xv-above-grid-list {
+ border: 0;
}
-.xv-list.xv-grid-list {
+.xv-grid-box .xv-scroller {
background: #f8f8f8;
}
-.xv-list.xv-grid-list .xv-list-item > * {
- vertical-align: top;
+.xv-limit-description .xv-grid-box .xv-grid-attr.bold {
+ font-weight: bold;
}
-.xv-list.xv-grid-list .xv-list-item {
- padding-top: 7px !important;
- padding-bottom: 9px !important;
- border-bottom: 1px solid #aaaaaa !important;
- background: #f8f8f8;
+.xv-grid-box .xv-grid-attr.error {
+ color: #ff0000;
}
-.xv-list.xv-grid-list .xv-list-item.item-selected {
- background: #226b9a;
- background-color: #1f608c;
- background-image: -moz-linear-gradient(top, #226b9a, #1a4f77);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77));
- background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77);
- background-image: -o-linear-gradient(top, #226b9a, #1a4f77);
- background-image: linear-gradient(to bottom, #226b9a, #1a4f77);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0);
+.xv-grid-box .xv-grid-attr.emphasis {
+ color: #009000;
}
-.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr {
- color: #fdfdfd;
+.xv-grid-box .xv-grid-attr.warn {
+ color: #ff9c00;
}
-.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.placeholder {
+.xv-grid-box .xv-grid-attr.italic {
font-style: italic;
- color: #99ccff;
}
-.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.hyperlink {
- color: #ff6529;
+.xv-grid-box .xv-grid-attr.placeholder {
+ font-style: italic;
+ color: #93a1a1;
}
-.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.header {
- background: #99ccff;
+.xv-grid-box .xv-grid-attr.hyperlink {
+ color: blue;
}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column {
- vertical-align: top;
+.xv-grid-box .xv-gridbox-button {
+ color: #357ec7;
+ font-size: 18px;
+ border: none;
+ background: transparent;
}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr {
+.xv-grid-box .xv-grid-row {
font-size: 12px;
+ background-color: #d8d8d8;
+ border-bottom: 1px solid #aaaaaa;
+ vertical-align: top;
+ /**
+ This is the grid header row
+ */
}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.last {
- border-right: none;
+.xv-grid-box .xv-grid-row > * {
+ display: inline-block;
}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.name-column {
- padding-left: 7px;
+.xv-grid-box .xv-grid-row .xv-grid-header {
+ background-color: #d7d7d7;
+ color: #0e0e0e;
+ font-size: .8em;
+ font-weight: bold;
+ text-transform: uppercase;
+ padding-top: 4px;
}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.first {
- padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.second {
- padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.third {
- padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.short {
- padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.small {
- padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.medium {
- padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column.descr {
- padding-left: 7px;
-}
-.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr {
- padding: 0px;
-}
-.xv-list-attr {
- padding: 5px;
- font-size: .8em;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- color: #070707;
-}
-.xv-list-attr.header {
- padding: 4px;
- background: #d8d8d8;
- font-size: .7em;
- font-weight: bold;
- text-transform: uppercase;
- color: #fdfdfd;
-}
-.xv-list-attr.footer {
- padding: 4px;
- background: #d8d8d8;
- font-size: .7em;
- font-weight: bold;
- text-transform: uppercase;
- color: #070707;
-}
-.xv-list-attr.right {
- position: absolute;
- right: 10px;
-}
-.xv-list-attr.text-align-right {
- text-align: right;
-}
-.xv-list-attr.bold {
- font-weight: bold;
-}
-.xv-list-attr.error {
- color: #ff0000;
-}
-.xv-list-attr.emphasis {
- color: #009000;
-}
-.xv-list-attr.warn {
- color: #ff9c00;
-}
-.xv-list-attr.italic {
- font-style: italic;
-}
-.xv-list-attr.placeholder {
- font-style: italic;
- color: #777777;
-}
-.xv-list-attr.hyperlink {
- color: #357ec7;
- cursor: pointer;
-}
-.xv-list-attr.disabled {
- color: #777777;
-}
-/* Navigator */
-.xv-navigator-header {
- font-size: small;
- font-weight: bold;
- text-transform: uppercase;
- color: #ff6600;
- padding-left: 20px;
- border-bottom: 1px solid #0e0e0e;
-}
-.xv-workspace-header {
- color: #fdfdfd;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- padding: 8px 0 0 8px;
-}
-/**
- * Default ListItem styles when using a ModelDecorator.
- */
-.xv-list .xv-model-decorator > .xv-list-item .xv-table {
- display: table;
- width: 100%;
- table-layout: fixed;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-table .xv-cell {
- display: table-cell;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr {
- /**
- * Default styling for a model's id (as designated by 'idAttribute')
- */
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-id {
- color: #357ec7;
- font-weight: bold;
- cursor: pointer;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attribute-name {
- font-weight: bold;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-number {
- text-align: right;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-money {
- text-align: right;
-}
-.xv-list .xv-model-decorator > .xv-list-item .xv-list-column.xv-list-attr.xm-attributetype-date {
- text-align: right;
-}
-.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr {
- color: white;
-}
-.xv-list .xv-model-decorator > .xv-list-item.item-selected .xv-list-attr.xm-attribute-id {
- color: #ff6529;
-}
-/**
- Styles related to pickers, combo boxes, and relation widgets
-*/
-.onyx-picker-decorator .onyx-button {
- padding: 12px 8px 12px 8px;
- width: 150px;
-}
-.onyx-picker .onyx-menu-item {
- text-align: left;
- text-overflow: ellipsis;
-}
-.picker-icon {
- position: absolute;
- right: 0;
- margin: 0 10px 0 2px;
- color: #070707;
-}
-.xv-picker-button {
- text-align: left;
-}
-.xv-picker-button .picker-content {
- max-width: 100px;
- overflow: hidden;
-}
-.xv-picker-button.disabled {
- color: #777777;
-}
-.xv-picker-label {
- color: #070707;
- padding: 20px 8px 8px 8px;
- text-align: right;
- width: 130px;
-}
-.xv-picker-label.disabled {
- color: #777777;
-}
-.xv-combobox-note {
- padding: 14px 3px 8px 3px;
- text-align: left;
-}
-/*
- Styles relating to the grid box
-*/
-/* Entire box including the grid and the summary panel */
-.xv-grid-box {
- /**
- This is the most general grid row that
- is not specific to read-only or selected
- */
-}
-.xv-grid-box.small-panel {
- width: 600px;
-}
-.xv-grid-box.medium-panel {
- width: 700px;
-}
-.xv-grid-box.large-panel {
- width: 800px;
-}
-.xv-grid-box .enyo-list-page > *:first-child .xv-grid-row {
- border-top: 0;
-}
-.xv-grid-box .xv-above-grid-list {
- border: 0;
-}
-.xv-grid-box .xv-scroller {
- background: #f8f8f8;
-}
-.xv-limit-description .xv-grid-box .xv-grid-attr.bold {
- font-weight: bold;
-}
-.xv-grid-box .xv-grid-attr.error {
- color: #ff0000;
-}
-.xv-grid-box .xv-grid-attr.emphasis {
- color: #009000;
-}
-.xv-grid-box .xv-grid-attr.warn {
- color: #ff9c00;
-}
-.xv-grid-box .xv-grid-attr.italic {
- font-style: italic;
-}
-.xv-grid-box .xv-grid-attr.placeholder {
- font-style: italic;
- color: #93a1a1;
-}
-.xv-grid-box .xv-grid-attr.hyperlink {
- color: blue;
-}
-.xv-grid-box .xv-gridbox-button {
- color: #357ec7;
- font-size: 18px;
- border: none;
- background: transparent;
-}
-.xv-grid-box .xv-grid-row {
- font-size: 12px;
- background-color: #d8d8d8;
- border-bottom: 1px solid #aaaaaa;
- vertical-align: top;
- /**
- This is the grid header row
- */
-}
-.xv-grid-box .xv-grid-row > * {
- display: inline-block;
-}
-.xv-grid-box .xv-grid-row .xv-grid-header {
- background-color: #d7d7d7;
- color: #0e0e0e;
- font-size: .8em;
- font-weight: bold;
- text-transform: uppercase;
- padding-top: 4px;
-}
-.xv-grid-box .xv-grid-row .xv-grid-header.last {
- border-right: none;
+.xv-grid-box .xv-grid-row .xv-grid-header.last {
+ border-right: none;
}
.xv-grid-box .xv-grid-row > * {
padding: 6px 4px;
text-align: center;
font-size: 24px;
}
+/**
+ Styles relating to Lists
+*/
+.xv-list-header {
+ background-color: #d8d8d8;
+ color: #fdfdfd;
+ font-size: .6em;
+ font-weight: bold;
+ text-transform: uppercase;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ border-bottom: 1px solid #aaaaaa;
+}
+.xv-list-header .xv-list-column.last {
+ border-right: none;
+}
+.xv-list-header .xv-list-column.name-column,
+.xv-list-header .xv-list-column.first,
+.xv-list-header .xv-list-column.second,
+.xv-list-header .xv-list-column.third,
+.xv-list-header .xv-list-column.short,
+.xv-list-header .xv-list-column.small,
+.xv-list-header .xv-list-column.medium,
+.xv-list-header .xv-list-column.descr {
+ padding-left: 7px;
+}
+/* List */
+.xv-list-column.line-number {
+ width: 30px;
+ text-align: right;
+}
+.xv-list-column.name-column {
+ width: 200px;
+}
+.xv-list-column.right-column {
+ width: 100px;
+ text-align: right;
+}
+.xv-list-column.short {
+ width: 100px;
+}
+.xv-list-column.small {
+ width: 125px;
+}
+.xv-list-column.medium {
+ width: 150px;
+}
+.xv-list-column.first {
+ width: 300px;
+}
+.xv-list-column.second {
+ width: 200px;
+}
+.xv-list-column.third {
+ width: 100px;
+}
+.xv-list-column.money,
+.xv-list-column.quantity {
+ width: 75px;
+ text-align: right;
+}
+.xv-list-column.descr {
+ width: 200px;
+}
+.xv-list-column.icon {
+ width: 10px;
+}
+.xv-list {
+ background: #f8f8f8;
+}
+.xv-list .xv-list-item > * {
+ display: inline-block;
+ vertical-align: middle;
+}
+.xv-list .xv-list-item {
+ background-color: #fdfdfd;
+ border-bottom: 1px solid #d7d7d7;
+ min-height: 32px;
+}
+.xv-list .xv-list-item.header {
+ padding-top: 0;
+}
+.xv-list .xv-list-item.inactive {
+ background-color: #d8d8d8;
+ color: #070707;
+}
+.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr {
+ background: transparent;
+}
+.xv-list .xv-list-item.inactive .xv-list-column .xv-list-attr.placeholder {
+ color: #d8d8d8;
+}
+.xv-list .xv-list-item .xv-list-column .list-icon {
+ padding: 2px;
+ color: #666666;
+ vertical-align: sub;
+ border: 1px solid #efefef;
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+}
+.xv-list .xv-list-item.item-selected {
+ background: #226b9a;
+ background-color: #1f608c;
+ background-image: -moz-linear-gradient(top, #226b9a, #1a4f77);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77));
+ background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77);
+ background-image: -o-linear-gradient(top, #226b9a, #1a4f77);
+ background-image: linear-gradient(to bottom, #226b9a, #1a4f77);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0);
+}
+.xv-list .xv-list-item.item-selected .xv-list-attr {
+ color: #fdfdfd;
+}
+.xv-list .xv-list-item.item-selected .xv-list-attr.placeholder {
+ font-style: italic;
+ color: #99ccff;
+}
+.xv-list .xv-list-item.item-selected .xv-list-attr.hyperlink {
+ color: #ff6529;
+}
+.xv-list .xv-list-item.item-selected .xv-list-attr.header {
+ background: #99ccff;
+}
+.xv-list .xv-list-item .xv-list-item-gear {
+ position: absolute;
+ right: 0px;
+ z-index: 999;
+}
+.xv-list.xv-grid-list {
+ background: #f8f8f8;
+}
+.xv-list.xv-grid-list .xv-list-item > * {
+ vertical-align: top;
+}
+.xv-list.xv-grid-list .xv-list-item {
+ padding-top: 7px !important;
+ padding-bottom: 9px !important;
+ border-bottom: 1px solid #aaaaaa !important;
+ background: #f8f8f8;
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected {
+ background: #226b9a;
+ background-color: #1f608c;
+ background-image: -moz-linear-gradient(top, #226b9a, #1a4f77);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#226b9a), to(#1a4f77));
+ background-image: -webkit-linear-gradient(top, #226b9a, #1a4f77);
+ background-image: -o-linear-gradient(top, #226b9a, #1a4f77);
+ background-image: linear-gradient(to bottom, #226b9a, #1a4f77);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff226b9a', endColorstr='#ff1a4f77', GradientType=0);
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr {
+ color: #fdfdfd;
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.placeholder {
+ font-style: italic;
+ color: #99ccff;
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.hyperlink {
+ color: #ff6529;
+}
+.xv-list.xv-grid-list .xv-list-item.item-selected .xv-list-attr.header {
+ background: #99ccff;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column {
+ vertical-align: top;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr {
+ font-size: 12px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.last {
+ border-right: none;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.name-column {
+ padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.first {
+ padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.second {
+ padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.third {
+ padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.short {
+ padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.small {
+ padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.medium {
+ padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column.descr {
+ padding-left: 7px;
+}
+.xv-list.xv-grid-list .xv-list-item .xv-list-column .xv-list-attr {
+ padding: 0px;
+}
+.xv-list-attr {
+ padding: 5px;
+ font-size: .8em;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ color: #070707;
+}
+.xv-list-attr.header {
+ padding: 4px;
+ background: #d8d8d8;
+ font-size: .7em;
+ font-weight: bold;
+ text-transform: uppercase;
+ color: #fdfdfd;
+}
+.xv-list-attr.footer {
+ padding: 4px;
+ background: #d8d8d8;
+ font-size: .7em;
+ font-weight: bold;
+ text-transform: uppercase;
+ color: #070707;
+}
+.xv-list-attr.right {
+ position: absolute;
+ right: 10px;
+}
+.xv-list-attr.text-align-right {
+ text-align: right;
+}
+.xv-list-attr.bold {
+ font-weight: bold;
+}
+.xv-list-attr.error {
+ color: #ff0000;
+}
+.xv-list-attr.emphasis {
+ color: #009000;
+}
+.xv-list-attr.warn {
+ color: #ff9c00;
+}
+.xv-list-attr.italic {
+ font-style: italic;
+}
+.xv-list-attr.placeholder {
+ font-style: italic;
+ color: #777777;
+}
+.xv-list-attr.hyperlink {
+ color: #357ec7;
+ cursor: pointer;
+}
+.xv-list-attr.disabled {
+ color: #777777;
+}
+/* Navigator */
+.xv-navigator-header {
+ font-size: small;
+ font-weight: bold;
+ text-transform: uppercase;
+ color: #ff6600;
+ padding-left: 20px;
+ border-bottom: 1px solid #0e0e0e;
+}
+.xv-workspace-header {
+ color: #fdfdfd;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ padding: 8px 0 0 8px;
+}
/**
Styles relating to widgets in the pullout
*/
{name: "startupProgressBar", kind: "onyx.ProgressBar",
classes: "xv-startup-progress onyx-progress-button", progress: 0}
]},
- {kind: "onyx.Popup", name: "notifyPopup", centered: true,
+ {kind: "onyx.Popup", name: "notifyPopup", classes: "xv-popup", centered: true,
onHide: "notifyHidden",
modal: true, floating: true, scrim: true, components: [
- {name: "notifyMessage"},
- {tag: "br"},
- {kind: "onyx.Button", content: "_ok".loc(), name: "notifyOk", ontap: "notifyTap",
- classes: "xv-popup-button", showing: false},
- {kind: "onyx.Button", content: "_yes".loc(), name: "notifyYes", ontap: "notifyTap",
- classes: "xv-popup-button", showing: false},
- {kind: "onyx.Button", content: "_no".loc(), name: "notifyNo", ontap: "notifyTap",
- classes: "xv-popup-button", showing: false},
- {kind: "onyx.Button", content: "_cancel".loc(), name: "notifyCancel", ontap: "notifyTap",
- classes: "xv-popup-button", showing: false}
+ {name: "notifyMessage", classes: "message"},
+ {classes: "xv-buttons", name: "notifyButtons", components: [
+ {kind: "onyx.Button", content: "_ok".loc(), name: "notifyOk", ontap: "notifyTap",
+ showing: false, classes: "text"},
+ {kind: "onyx.Button", content: "_yes".loc(), name: "notifyYes", ontap: "notifyTap",
+ showing: false, classes: "text"},
+ {kind: "onyx.Button", content: "_no".loc(), name: "notifyNo", ontap: "notifyTap",
+ showing: false, classes: "text"},
+ {kind: "onyx.Button", content: "_cancel".loc(), name: "notifyCancel", ontap: "notifyTap",
+ showing: false, classes: "text"}
+ ]}
]},
{kind: "onyx.Popup", name: "popupWorkspace", classes: "xv-popup xv-groupbox-popup", centered: true,
autoDismiss: false, modal: true, floating: true, scrim: true},
resizeHandler: function () {
this.inherited(arguments);
if (this.$.notifyPopup.showing) {
- this.$.notifyPopup.applyStyle("opacity", 1); // XXX not sure why this hack is necessary.
+ // This is a fix for an enyo bug that renders the popup as clear
+ this.$.notifyPopup.applyStyle("opacity", 1);
}
},
activate: function () {
return this.$.navigator;
},
getNotifyButtons: function () {
- return _.filter(this.$, function (control) {
- return control.name.substring(0, 6) === 'notify' && control.kind === 'onyx.Button';
- });
+ return this.$.notifyButtons.controls;
},
getStartupProgressBar: function () {
return this.$.startupProgressBar;
inEvent.type = inEvent.type || XM.Model.NOTICE;
// show the appropriate buttons
- _.each(this.$.notifyPopup.children, function (component) {
- if (component.kind !== "onyx.Button") {
- // not a button: do nothing.
- } else if (_.indexOf(typeToButtonMap[String(inEvent.type)], component.name) >= 0) {
- // in the show-me array, so show
- component.setShowing(true);
- } else {
- // not in the show-me array, so hide
- component.setShowing(false);
- }
+ _.each(this.getNotifyButtons(), function (component) {
+ component.setShowing(_.indexOf(typeToButtonMap[String(inEvent.type)], component.name) >= 0);
});
-
// allow custom button text
this.$.notifyYes.setContent(inEvent.yesLabel || "_yes".loc());
this.$.notifyNo.setContent(inEvent.noLabel || "_no".loc());
// it's the OK button unless it's a 2- or 3- way question, in which case it's YES
this._activeNotify = inEvent.type === XM.Model.QUESTION || inEvent.type === XM.Model.YES_NO_CANCEL ? 1 : 0;
_.each(this.getNotifyButtons(), function (button, index) {
- button.addRemoveClass("onyx-blue", index === that._activeNotify);
+ button.addRemoveClass("selected", index === that._activeNotify);
});
// delete out any previously added customComponents/customComponentControls
// Add the custom component
if (inEvent.component) {
inEvent.component.name = "customComponent";
- inEvent.component.addBefore = this.$.notifyOk;
+ // can add styling class here instead of inline css
+ inEvent.component.addBefore = this.$.notifyButtons;
this.$.notifyPopup.createComponent(inEvent.component);
- this.$.notifyPopup.$.customComponent.addStyles("color:black;");
if (inEvent.componentModel) {
this.$.notifyPopup.$.customComponent.setValue(inEvent.componentModel);
}
this._notifyDone = false;
this.$.notifyPopup.render();
this.$.notifyPopup.show();
- this.$.notifyPopup.applyStyle("opacity", 1); // XXX not sure why this hack is necessary.
+ // Without this fix, the popup renders transparent
+ this.$.notifyPopup.applyStyle("opacity", 1);
},
notifyHidden: function () {
if (!this._notifyDone) {
} else if (keyCode === 37 || (keyCode === 9 && isShift)) {
// left or shift-tab
- notifyButtons[activeIndex].removeClass("onyx-blue");
+ notifyButtons[activeIndex].removeClass("selected");
for (nextShowing = activeIndex - 1; nextShowing >= 0; nextShowing--) {
if (nextShowing === 0 && !notifyButtons[nextShowing].showing) {
// there are no showing buttons to the left
activeIndex = nextShowing;
}
this._activeNotify = activeIndex;
- notifyButtons[activeIndex].addClass("onyx-blue");
+ notifyButtons[activeIndex].addClass("selected");
} else if (keyCode === 39 || keyCode === 9) {
// right or tab
- notifyButtons[activeIndex].removeClass("onyx-blue");
+ notifyButtons[activeIndex].removeClass("selected");
for (nextShowing = activeIndex + 1; nextShowing < notifyButtons.length; nextShowing++) {
if (nextShowing + 1 === notifyButtons.length && !notifyButtons[nextShowing].showing) {
// there are no showing buttons to the right
}
this._activeNotify = activeIndex;
- notifyButtons[activeIndex].addClass("onyx-blue");
+ notifyButtons[activeIndex].addClass("selected");
}
},
/**
maxHeight: "400px",
horizontal: "hidden"
}, {owner: this});
- this.$.popupWorkspace.createComponent({name: "workspace", kind: inEvent.workspace, container: this.$.popupScroller});
+ this.$.popupWorkspace.createComponent({name: "workspace", kind: inEvent.workspace,
+ container: this.$.popupScroller});
+ // TODO: inline css - git rid of it!
this.$.popupWorkspace.$.workspace.addStyles("color:black;");
this.$.popupWorkspace.$.workspace.setValue(inEvent.model);
- this.$.popupWorkspace.createComponent({
+ // create button bar
+ this.$.popupWorkspace.createComponent({classes: "xv-buttons", name: "workspaceButtons"}, {owner: this});
+ this.$.workspaceButtons.createComponents([{
kind: "onyx.Button",
content: "_save".loc(),
name: "popupWorkspaceSave",
ontap: "popupWorkspaceTap",
- classes: "onyx-blue xv-popup-button"
- }, {owner: this});
- this.$.popupWorkspace.createComponent({
+ classes: "selected text"
+ },
+ {
kind: "onyx.Button",
content: "_cancel".loc(),
name: "popupWorkspaceCancel",
ontap: "popupWorkspaceTap",
- classes: "xv-popup-button"
- }, {owner: this});
-
+ classes: "text"
+ }], {owner: this});
this.$.popupWorkspace.render();
this.$.popupWorkspace.show();
- this.$.popupWorkspace.applyStyle("opacity", 1); // XXX not sure why this hack is necessary.
+ // Without this fix, the popup renders transparent
+ this.$.popupWorkspace.applyStyle("opacity", 1);
},
popupWorkspaceTap: function (inSender, inEvent) {
var model = this.$.popupWorkspace.$.workspace.value,
(function () {
"use strict";
- var ursa = require("ursa"),
- exec = require("child_process").exec,
+ var exec = require("child_process").exec,
forge = require("node-forge"),
spawn = require("child_process").spawn,
async = require("async"),
res.send({isError: true, error: err});
},
genKey = function (model, result) {
- /**
- * This is REALLY slow in pure javascript. ursa is much faster.
- * @See: https://github.com/digitalbazaar/forge/issues/125
- forge.pki.rsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) {
+ forge.pki.rsa.generateKeyPair({bits: 2048, workers: -1}, function (err, keypair) {
if (err) {
res.send({isError: true, message: "Error generating keypair: " + err.message, error: err});
return;
fetchSuccess(model, result, keypair);
});
- */
-
- // Use ursa for the key gen and then convert to forge's format.
- var keypair = ursa.generatePrivateKey();
- var keys = {
- privateKey: forge.pki.privateKeyFromPem(keypair.toPrivatePem().toString()),
- publicKey: forge.pki.publicKeyFromPem(keypair.toPublicPem().toString())
- };
-
- fetchSuccess(model, result, keys);
},
sendP12 = function (keys) {
// It's possible and much easier to generate the p12 file without a
// 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));
- });
});
}());
"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",
"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"
},
"googleapis": "~0.4.6"
},
"engines": {
- "node": "0.8.x"
+ "node": "^0.10"
},
"main": "node-datasource/main.js",
"scripts": {
python-software-properties \
software-properties-common
-NODE_VERSION=0.8.26
+NODE_VERSION=0.10.31
DEBDIST=`lsb_release -c -s`
echo "Trying to install xTuple for platform ${DEBDIST}"
sudo nvm alias xtuple $NODE_VERSION
# use latest npm
- npm install -g npm@1.4.25
+ npm install -fg npm@1.4.25
# npm no longer supports its self-signed certificates
log "telling npm to use known registrars..."
npm config set ca ""
"use strict";
var async = require("async"),
- exec = require('child_process').exec,
+ proc = require('child_process'),
path = require('path'),
os = require('os'),
winston = require('winston'),
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);
}
smoke = require("../../lib/smoke");
describe('Configuration Workspaces', function () {
- this.timeout(30 * 1000);
+ this.timeout(60 * 1000);
before(function (done) {
zombieAuth.loadApp(done);
});
it('should all be accessible', function (done) {
- this.timeout(80 * 1000);
+ this.timeout(120 * 1000);
var navigator, workspace,
list,
i = -1;
assert = require("chai").assert;
describe('Workspaces', function () {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
it('should log in first', function (done) {
zombieAuth.loadApp(done);
});
var workspaceContainer, workspace, model, id, moduleContainer;
beforeEach(function (done) {
- this.timeout(10 * 1000);
+ this.timeout(60 * 1000);
smoke.navigateToExistingWorkspace(XT.app, "XV.ClassCodeList", function (_workspaceContainer) {
workspaceContainer = _workspaceContainer;
});
});
afterEach(function (done) {
- this.timeout(10 * 1000);
+ this.timeout(60 * 1000);
// maybe one of the tests already released the lock
if (!model.hasLockKey()) {
});
afterEach(function (done) {
- this.timeout(10 * 1000);
+ this.timeout(30 * 1000);
// restore permissions
_.extend(XT.session.privileges.attributes, originalPrivileges);
});
};
- describe('Sales Order Workspace', function () {
+ // TODO: move to sales order spec
+ describe.skip('Sales Order Workspace', function () {
this.timeout(30 * 1000);
//
moduleContainer = XT.app.$.postbooks;
/** Open the first model's salesOrderLineWorkspace...
- Copied from gridBox buttonTapped function (expandGridRowButton)
+ Copied from gridBox buttonTapped function (expandGridRowButton)
*/
lineItemBox.doChildWorkspace({
workspace: lineItemBox.getWorkspace(),
index: lineItemBox.getValue().indexOf(model)
});
- /** The line item's workspace model has been deleted (DESTROYED_CLEAN).
+ /** The line item's workspace model has been deleted (DESTROYED_CLEAN).
Client is now in SalesOrderWorkspace.
*/
var statusChanged = function () {
model.once("status:DESTROYED_CLEAN", statusChanged);
- // Function to keep checking for notifyPopup showing and then tap yes.
+ // Function to keep checking for notifyPopup showing and then tap yes.
// This will fire right after the delete below.
var notifyPopupInterval = setInterval(function () {
if (!moduleContainer.$.notifyPopup.showing) { return; }
// Step 1: load the environment with Zombie
//
it('can be loaded with a zombie session', function (done) {
- this.timeout(40 * 1000);
+ this.timeout(60 * 1000);
zombieAuth.loadApp({callback: done, verbose: data.verbose,
loginDataPath: data.loginDataPath});
});
// Step 3: initialize the model to get the ID from the database
//
it('can be initialized by fetching an id from the server', function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
init(data, done);
});
//
_.each(data.beforeSetActions || [], function (spec) {
it(spec.it, function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
spec.action(data, done);
});
});
it('can have its values set', function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
data.updated = false;
setModel(data, done);
});
// if this model has comments, set them on the model
if (data.commentType) {
it('can have its comments set', function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
setComments(data, done);
});
}
_.each(data.beforeSaveActions || [], function (spec) {
it(spec.it, function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
spec.action(data, done);
});
});
//
if (!data.skipSave) {
it('can be saved to the database', function (done) {
- this.timeout(10 * 1000);
+ this.timeout(60 * 1000);
save(data, done);
});
_.each(data.afterSaveActions || [], function (spec) {
it(spec.it, function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
spec.action(data, done);
});
});
// Step 7: save the updated model to the database
//
it('can be re-saved to the database', function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
save(data, done);
});
}
//
_.each(data.beforeDeleteActions || [], function (spec) {
it(spec.it, function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
spec.action(data, done);
});
});
if (!data.skipDelete) {
it('can be deleted from the database', function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
destroy(data, done);
});
}
_.each(data.afterDeleteActions || [], function (spec) {
it(spec.it, function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
spec.action(data, done);
});
});
exports.updateFirstModel = function (test) {
it('should allow a trivial update to the first model of ' + test.kind, function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
navigateToExistingWorkspace(XT.app, test.kind, function (workspaceContainer) {
var updateObj,
statusChanged,
var workspaceContainer,
workspace;
it('can get to a new workspace', function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
navigateToNewWorkspace(XT.app, spec.listKind, function (_workspaceContainer) {
workspaceContainer = _workspaceContainer;
done();
});
_.each(spec.beforeSaveUIActions || [], function (spec) {
it(spec.it, function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
spec.action(workspace, done);
});
});
it('can save the workspace', function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
if (spec.captureObject) {
XG = XG || {};
XG.capturedId = workspace.value.id;
});
_.each(spec.afterSaveUIActions || [], function (spec) {
it(spec.it, function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
spec.action(workspace, done);
});
});
return;
}
it('can delete the item from the list', function (done) {
- this.timeout(20 * 1000);
+ this.timeout(60 * 1000);
deleteFromList(XT.app, workspace.value, done);
});
};
regexp:true, undef:true, strict:true, trailing:true, white:true */
/*global XT:true, XM:true, XV:true, XZ:true, enyo:true, XG:true */
+var _ = require('underscore');
+global.URL = require('url');
+var parse = global.URL.parse;
+var resolve = global.URL.resolve;
+global.URL.parse = function (url) {
+ "use strict";
+ console.log('URL.parse', url);
+ if (_.isObject(url) && _.isString(url.href)) {
+ return parse(url.href);
+ }
+ else {
+ return parse(url);
+ }
+};
+global.URL.resolve = function (from, to) {
+ "use strict";
+ console.log('URL.resolve from', from);
+ console.log('URL.resolve to', to);
+ if (_.isObject(from)) {
+ from = from.href || '/';
+ }
+ if (_.isObject(to)) {
+ to = to.href || '';
+ }
+
+ return resolve(from, to);
+};
+
+
// global objects
enyo = {};
XT = {};
XV = {};
XZ = {}; // xTuple Zombie. Used to help zombie within the context of these tests.
+// https://github.com/mikeal/request/issues/418#issuecomment-17149236
+process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
+
var assert = require('assert'),
zombie = require('zombie'),
- URL = require('url'),
_ = require('underscore');
return;
}
- var parse = URL.parse;
- URL.parse = function (url) {
- if (_.isObject(url) && _.isString(url.href)) {
- return parse(url.href);
- }
- else {
- return parse(url);
- }
- };
- zombie.visit(host, {debug: verboseMode}, function (e, browser) {
+ zombie.visit(host, {debug: verboseMode, runScripts: false}, function (e, browser) {
if (e) {
- //console.log("Zombie visit error: ", e);
+ console.log("Zombie visit error: ", e);
}
//
// This is the login screen
//
+ browser.runScripts = true;
browser
.fill('id', username)
.fill('password', password)