Merge pull request #1609 from xtuple/4_5_x
[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 */
6
7 (function () {
8   "use strict";
9
10   var zombieAuth = require("../../lib/zombie_auth"),
11     _ = require("underscore"),
12     async = require("async"),
13     submodels,
14     smoke = require("../../lib/smoke"),
15     assert = require("chai").assert,
16     gridRow,
17     gridBox,
18     workspace,
19     skipIfSiteCal,
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(20 * 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         if (XT.extensions.manufacturing && XT.session.settings.get("UseSiteCalendar")) {skipIfSiteCal = true; }
60       });
61     });
62
63     describe('User selects to create a sales order', function () {
64       it('User navigates to Sales Order-New and selects to create a new Sales order', function (done) {
65         smoke.navigateToNewWorkspace(XT.app, "XV.SalesOrderList", function (workspaceContainer) {
66           workspace = workspaceContainer.$.workspace;
67
68           assert.equal(workspace.value.recordType, "XM.SalesOrder");
69           //
70           // Set the customer from the appropriate workspace quantityWidget
71           //
72           var createHash = {
73             customer: submodels.customerModel
74           };
75           // TODO: why is the first shipto getting stripped out of TTOYS by now?
76           //assert.equal(submodels.customerModel.get("shiptos").length, 3);
77           //assert.equal(submodels.customerModel.getDefaultShipto().getValue("address.city"), "Alexandoria");
78           smoke.setWorkspaceAttributes(workspace, createHash);
79           //assert.equal(workspace.value.getValue("shipto.address.city"), "Alexandria");
80           // In sales order, setting the line item fields will set off a series
81           // of asynchronous calls. Once the "total" field is computed, we
82           // know that the workspace is ready to save.
83           // It's good practice to set this trigger *before* we change the line
84           // item fields, so that we're 100% sure we're ready for the responses.
85           workspace.value.once("change:total", function () {
86             done();
87             /* The following save was moved to the second test
88             smoke.saveWorkspace(workspace, function (err, model) {
89               assert.isNull(err);
90               // TODO: sloppy
91               setTimeout(function () {
92                 smoke.deleteFromList(XT.app, model, done);
93               }, 2000);
94             });*/
95           });
96
97           //
98           // Set the line item fields
99           //
100           // Be sure that there are no rows
101           gridBox = workspace.$.salesOrderLineItemBox;
102           assert.equal(gridBox.liveModels().length, 0);
103
104           gridBox.newItem();
105           gridRow = gridBox.$.editableGridRow;
106
107           gridRow.$.itemSiteWidget.doValueChange({value: {item: submodels.itemModel, site: submodels.siteModel}});
108           gridRow.$.quantityWidget.doValueChange({value: 5});
109
110           // Verify that there is currently one row
111           assert.equal(gridBox.liveModels().length, 1);
112         });
113       });
114       it('Supply list should have action to open Item Workbench', function (done) {
115         if (!XT.extensions.inventory) {
116           done();
117           return;
118         }
119         var verify,
120           action = _.find(gridBox.$.supplyList.actions, function (action) {
121             return action.name === "openItemWorkbench";
122           }),
123           prereq = action.prerequisite;
124         gridBox.$.supplyButton.bubble("ontap");
125         gridBox.$.supplyList.select(0);
126
127         gridBox.$.supplyList.value.models[0][prereq](function (hasPriv) {
128           assert.isTrue(hasPriv);
129           if (hasPriv) {
130             gridBox.$.supplyList.actionSelected(null, {action: {method: "openItemWorkbench"}, index: 0});
131
132             setTimeout(function () {
133               assert.equal(XT.app.$.postbooks.getActive().$.workspace.kind, "XV.ItemWorkbenchWorkspace");
134               XT.app.$.postbooks.getActive().doPrevious();
135               assert.equal(XT.app.$.postbooks.getActive().$.workspace.kind, "XV.SalesOrderWorkspace");
136               done();
137             }, 3000);
138           } else {done(); }
139         });
140       });
141       it('adding a second line item should not copy the item', function (done) {
142         workspace.value.once("change:total", done());
143
144         gridRow.$.itemSiteWidget.$.privateItemSiteWidget.$.input.focus();
145         // Add a new item, check that row exists, and make sure the itemSiteWidget doesn't copy irrelevantly
146         gridBox.newItem();
147         assert.equal(gridBox.liveModels().length, 2);
148         assert.notEqual(submodels.itemModel.id, gridRow.$.itemSiteWidget.$.privateItemSiteWidget.$.input.value);
149
150         // The intention was to delete the above line after verifying that the item doesn't copy but ran into 
151         // many issues so just populating with same data and saving it with 2 line items.
152         gridRow.$.itemSiteWidget.doValueChange({value: {item: submodels.itemModel, site: submodels.siteModel}});
153         gridRow.$.quantityWidget.doValueChange({value: 5});
154
155         /* Delete the line item
156         workspace.value.get("lineItems").models[1].destroy({
157               success: function () {
158                 gridBox.setEditableIndex(null);
159                 gridBox.$.editableGridRow.hide();
160                 gridBox.valueChanged();
161               }
162             });
163         */
164       });
165       // XXX - skip test if site calendar is enabled -
166       // temporary until second notifyPopup (_nextWorkingDate) is handled in test (TODO).
167
168       //it('changing the Schedule Date updates the line item\'s schedule date', function (done) {
169       (skipIfSiteCal ? it.skip : it)(
170         'changing the Schedule Date updates the line item\'s schedule date', function (done) {
171         var getDowDate = function (dow) {
172             var date = new Date(),
173               currentDow = date.getDay(),
174               distance = dow - currentDow;
175             date.setDate(date.getDate() + distance);
176             return date;
177           },
178           newScheduleDate = getDowDate(0); // Sunday from current week
179
180         var handlePopup = function () {
181           assert.equal(workspace.value.get("scheduleDate"), newScheduleDate);
182           // Confirm to update all line items
183           XT.app.$.postbooks.notifyTap(null, {originator: {name: "notifyYes"}});
184           // And verify that they were all updated with the new date
185           setTimeout(function () {
186             _.each(workspace.value.get("lineItems").models, function (model) {
187               assert.equal(newScheduleDate, model.get("scheduleDate"));
188             });
189             done();
190           }, 3000);
191         };
192
193         workspace.value.once("change:scheduleDate", handlePopup);
194         workspace.value.set("scheduleDate", newScheduleDate);
195       });
196       it('save, then delete order', function (done) {
197         assert.equal(workspace.value.status, XM.Model.READY_NEW);
198         smoke.saveWorkspace(workspace, function (err, model) {
199           assert.isNull(err);
200           // TODO: sloppy
201           setTimeout(function () {
202             smoke.deleteFromList(XT.app, model, done);
203           }, 4000);
204         }, true);
205       });
206     });
207   });
208 }());