Trigger checking MaintainUsers priv before updating table to avoid bug 24255
[xtuple] / test / extensions / sales / sales_order_workspace.js
1 /*jshint trailing:true, white:true, indent:2, strict:true, curly:true,
2   immed:true, eqeqeq:true, forin:true, latedef:true,
3   newcap:true, noarg:true, undef:true */
4 /*global XT:true, XM:true, XV:true, describe:true, it:true, setTimeout:true,
5   console:true, before:true, after:true, module:true, require:true, setInterval:true,
6   clearInterval:true */
7
8 (function () {
9   "use strict";
10
11   var zombieAuth = require("../../lib/zombie_auth"),
12     _ = require("underscore"),
13     async = require("async"),
14     submodels,
15     smoke = require("../../lib/smoke"),
16     assert = require("chai").assert,
17     gridRow,
18     gridBox,
19     workspace,
20     primeSubmodels = function (done) {
21       var submodels = {};
22       async.series([
23         function (callback) {
24           submodels.customerModel = new XM.SalesCustomer();
25           submodels.customerModel.fetch({number: "TTOYS", success: function () {
26             assert.equal(submodels.customerModel.get("shiptos").length, 3);
27             callback();
28           }});
29         },
30         function (callback) {
31           submodels.itemModel = new XM.ItemRelation();
32           submodels.itemModel.fetch({number: "BTRUCK1", success: function () {
33             callback();
34           }});
35         },
36         function (callback) {
37           submodels.siteModel = new XM.SiteRelation();
38           submodels.siteModel.fetch({code: "WH1", success: function () {
39             callback();
40           }});
41         }
42       ], function (err) {
43         done(err, submodels);
44       });
45     };
46
47   describe('Sales Order Workspace', function () {
48     this.timeout(30 * 1000);
49
50     //
51     // We'll want to have TTOYS, BTRUCK1, and WH1 onhand and ready for the test to work.
52     //
53     before(function (done) {
54       zombieAuth.loadApp(function () {
55         primeSubmodels(function (err, submods) {
56           submodels = submods;
57           done();
58         });
59       });
60     });
61
62     describe('User selects to create a sales order', function () {
63       it('User navigates to Sales Order-New and selects to create a new Sales order', function (done) {
64         smoke.navigateToNewWorkspace(XT.app, "XV.SalesOrderList", function (workspaceContainer) {
65           workspace = workspaceContainer.$.workspace;
66
67           assert.equal(workspace.value.recordType, "XM.SalesOrder");
68           //
69           // Set the customer from the appropriate workspace quantityWidget
70           //
71           var createHash = {
72             customer: submodels.customerModel
73           };
74           // TODO: why is the first shipto getting stripped out of TTOYS by now?
75           //assert.equal(submodels.customerModel.get("shiptos").length, 3);
76           //assert.equal(submodels.customerModel.getDefaultShipto().getValue("address.city"), "Alexandoria");
77           smoke.setWorkspaceAttributes(workspace, createHash);
78           //assert.equal(workspace.value.getValue("shipto.address.city"), "Alexandria");
79           // In sales order, setting the line item fields will set off a series
80           // of asynchronous calls. Once the "total" field is computed, we
81           // know that the workspace is ready to save.
82           // It's good practice to set this trigger *before* we change the line
83           // item fields, so that we're 100% sure we're ready for the responses.
84           workspace.value.once("change:total", function () {
85             done();
86             /* The following save was moved to the second test
87             smoke.saveWorkspace(workspace, function (err, model) {
88               assert.isNull(err);
89               // TODO: sloppy
90               setTimeout(function () {
91                 smoke.deleteFromList(XT.app, model, done);
92               }, 2000);
93             });*/
94           });
95
96           //
97           // Set the line item fields
98           //
99           // Be sure that there are no rows
100           gridBox = workspace.$.salesOrderLineItemBox;
101           assert.equal(gridBox.liveModels().length, 0);
102
103           gridBox.newItem();
104           gridRow = gridBox.$.editableGridRow;
105
106           gridRow.$.itemSiteWidget.doValueChange({value: {item: submodels.itemModel, site: submodels.siteModel}});
107           gridRow.$.quantityWidget.doValueChange({value: 5});
108
109           // Verify that there is currently one row
110           assert.equal(gridBox.liveModels().length, 1);
111         });
112       });
113       it('adding a second line item should not copy the item', function (done) {
114         workspace.value.once("change:total", done());
115
116         gridRow.$.itemSiteWidget.$.privateItemSiteWidget.$.input.focus();
117         // Add a new item, check that row exists, and make sure the itemSiteWidget doesn't copy irrelevantly
118         gridBox.newItem();
119         assert.equal(gridBox.liveModels().length, 2);
120         assert.notEqual(submodels.itemModel.id, gridRow.$.itemSiteWidget.$.privateItemSiteWidget.$.input.value);
121
122         // The intention was to delete the above line after verifying that the item doesn't copy but ran into
123         // many issues so just populating with same data and saving it with 2 line items.
124         gridRow.$.itemSiteWidget.doValueChange({value: {item: submodels.itemModel, site: submodels.siteModel}});
125         gridRow.$.quantityWidget.doValueChange({value: 5});
126
127         /* Delete the line item
128         workspace.value.get("lineItems").models[1].destroy({
129               success: function () {
130                 gridBox.setEditableIndex(null);
131                 gridBox.$.editableGridRow.hide();
132                 gridBox.valueChanged();
133               }
134             });
135         */
136       });
137       it('deleting an item through SalesOrderLineWorkspace should remove it from the line item ' +
138         'list', function (done) {
139         var lineItemBox = workspace.$.salesOrderLineItemBox,
140           model = lineItemBox.value.models[0],
141           startModelLength = lineItemBox.liveModels().length,
142           moduleContainer = XT.app.$.postbooks;
143
144         /** Open the first model's salesOrderLineWorkspace...
145             Copied from gridBox buttonTapped function (expandGridRowButton) 
146         */
147         lineItemBox.doChildWorkspace({
148           workspace: lineItemBox.getWorkspace(),
149           collection: lineItemBox.getValue(),
150           index: lineItemBox.getValue().indexOf(model)
151         });
152
153         /** The line item's workspace model has been deleted (DESTROYED_CLEAN). 
154             Client is now in SalesOrderWorkspace.
155         */
156         var statusChanged = function () {
157           assert.notEqual(startModelLength, lineItemBox.liveModels().length);
158           done();
159         };
160
161         model.once("status:DESTROYED_CLEAN", statusChanged);
162
163         // Function to keep checking for notifyPopup showing and then tap yes. 
164         // This will fire right after the delete below.
165         var notifyPopupInterval = setInterval(function () {
166           if (!moduleContainer.$.notifyPopup.showing) { return; }
167           clearInterval(notifyPopupInterval);
168           moduleContainer.notifyTap(null, {originator: {name: "notifyYes" }});
169         }, 100);
170         // Delete the item in the workspace
171         moduleContainer.getActive().deleteItem();
172       });
173
174       it('save, then delete order', function (done) {
175         assert.isTrue((workspace.value.status === XM.Model.READY_DIRTY ||
176           workspace.value.status === XM.Model.READY_NEW));
177         smoke.saveWorkspace(workspace, function (err, model) {
178           assert.isNull(err);
179           // XXX - sloppy
180           setTimeout(function () {
181             smoke.deleteFromList(XT.app, model, done);
182           }, 4000);
183         }, true);
184       });
185     });
186   });
187 }());