a2e4a73b892c9113dc9ef47f6b5dc5cee8029a7b
[xtuple] / enyo-client / application / source / widgets / relation.js
1 /*jshint node:true, indent:2, curly:true, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
2 regexp:true, undef:true, trailing:true, white:true, strict:false */
3 /*global XT:true, XV:true, XM:true, Backbone:true, window:true, enyo:true, _:true */
4
5 (function () {
6
7   // ..........................................................
8   // ACCOUNT
9   //
10
11   enyo.kind({
12     name: "XV.AccountWidget",
13     kind: "XV.RelationWidget",
14     collection: "XM.AccountRelationCollection",
15     list: "XV.AccountList"
16   });
17
18   // ..........................................................
19   // CONTACT
20   //
21
22   enyo.kind({
23     name: "XV.ContactWidget",
24     kind: "XV.RelationWidget",
25     label: "_contact".loc(),
26     collection: "XM.ContactRelationCollection",
27     list: "XV.ContactList",
28     keyAttribute: "name",
29     nameAttribute: "jobTitle",
30     descripAttribute: "phone",
31     classes: "xv-relationwidget",
32     published: {
33       showAddress: false
34     },
35     components: [
36       {kind: "FittableColumns", components: [
37         {name: "label", content: "", fit: true, classes: "xv-flexible-label"},
38         {kind: "onyx.InputDecorator", name: "decorator",
39           classes: "xv-input-decorator", components: [
40           {name: "input", kind: "onyx.Input", classes: "xv-subinput",
41             onkeyup: "keyUp", onkeydown: "keyDown", onblur: "receiveBlur",
42             onfocus: "receiveFocus"
43           },
44           {kind: "onyx.MenuDecorator", onSelect: "itemSelected", components: [
45             {kind: "onyx.IconButton", classes: "icon-folder-open-alt"},
46             {name: "popupMenu", floating: true, kind: "onyx.Menu",
47               components: [
48               {kind: "XV.MenuItem", name: "searchItem", content: "_search".loc()},
49               {kind: "XV.MenuItem", name: "openItem", content: "_open".loc(),
50                 disabled: true},
51               {kind: "XV.MenuItem", name: "newItem", content: "_new".loc(),
52                 disabled: true}
53             ]}
54           ]},
55           {name: "completer", kind: "XV.Completer", onSelect: "itemSelected"}
56         ]}
57       ]},
58       {kind: "FittableColumns", components: [
59         {name: "labels", classes: "xv-relationwidget-column left",
60           components: [
61           {name: "jobTitleLabel", content: "_jobTitle".loc() + ":",
62             classes: "xv-relationwidget-description label",
63             showing: false},
64           {name: "phoneLabel", content: "_phone".loc() + ":",
65             classes: "xv-relationwidget-description label",
66             showing: false},
67           {name: "alternateLabel", content: "_alternate".loc() + ":",
68             classes: "xv-relationwidget-description label",
69             showing: false},
70           {name: "faxLabel", content: "_fax".loc() + ":",
71             classes: "xv-relationwidget-description label",
72             showing: false},
73           {name: "primaryEmailLabel", content: "_email".loc() + ":",
74             classes: "xv-relationwidget-description label",
75             showing: false},
76           {name: "webAddressLabel", content: "_web".loc() + ":",
77             classes: "xv-relationwidget-description label",
78             showing: false},
79           {name: "addressLabel", content: "_address".loc() + ":",
80             classes: "xv-relationwidget-description label",
81             showing: false}
82         ]},
83         {name: "data", fit: true, components: [
84           {name: "name", classes: "xv-relationwidget-description hasLabel"},
85           {name: "description", ontap: "callPhone",
86             classes: "xv-relationwidget-description hasLabel hyperlink"},
87           {name: "alternate", classes: "xv-relationwidget-description hasLabel"},
88           {name: "fax", classes: "xv-relationwidget-description hasLabel"},
89           {name: "primaryEmail", ontap: "sendMail",
90             classes: "xv-relationwidget-description hasLabel hyperlink"},
91           {name: "webAddress", ontap: "openWindow",
92             classes: "xv-relationwidget-description hasLabel hyperlink"},
93           {name: "address", classes: "xv-relationwidget-description hasLabel",
94             allowHtml: true}
95         ]}
96       ]}
97     ],
98     disabledChanged: function () {
99       this.inherited(arguments);
100       var disabled = this.getDisabled();
101       if (this.$.phone) {
102         this.$.jobTitle.addRemoveClass("disabled", disabled);
103         this.$.phone.addRemoveClass("disabled", disabled);
104         this.$.alternate.addRemoveClass("disabled", disabled);
105         this.$.fax.addRemoveClass("disabled", disabled);
106         this.$.primaryEmail.addRemoveClass("disabled", disabled);
107         this.$.webAddress.addRemoveClass("disabled", disabled);
108       }
109     },
110     setValue: function (value, options) {
111       this.inherited(arguments);
112       if (value && !value.get) {
113         // the value of the widget is still being fetched asyncronously.
114         // when the value is fetched, this function will be run again,
115         // so for now we can just stop here.
116         return;
117       }
118       var jobTitle = value ? value.get("jobTitle") : "",
119         phone = value ? value.get("phone") : "",
120         alternate = value ? value.get("alternate") : "",
121         fax = value ? value.get("fax") : "",
122         primaryEmail = value ? value.get("primaryEmail") : "",
123         webAddress = value ? value.get("webAddress") : "",
124         address = value ? XM.Address.format(value.get("address")) : "",
125         showAddress = this.getShowAddress();
126       this.$.jobTitleLabel.setShowing(jobTitle);
127       this.$.phoneLabel.setShowing(phone);
128       this.$.alternate.setShowing(alternate);
129       this.$.alternate.setContent(alternate);
130       this.$.alternateLabel.setShowing(alternate);
131       this.$.fax.setShowing(fax);
132       this.$.fax.setContent(fax);
133       this.$.faxLabel.setShowing(fax);
134       this.$.primaryEmail.setShowing(primaryEmail);
135       this.$.primaryEmail.setContent(primaryEmail);
136       this.$.primaryEmailLabel.setShowing(primaryEmail);
137       this.$.webAddress.setShowing(webAddress);
138       this.$.webAddress.setContent(webAddress);
139       this.$.webAddressLabel.setShowing(webAddress);
140       this.$.address.setShowing(address && showAddress);
141       this.$.addressLabel.setShowing(address && showAddress);
142       if (showAddress) { this.$.address.setContent(address); }
143     },
144     openWindow: function () {
145       var address = this.value ? this.value.get("webAddress") : null;
146       if (address) { window.open("http://" + address); }
147       return true;
148     },
149     callPhone: function () {
150       var phoneNumber = this.value ? this.value.get("phone") : null,
151         win;
152       if (phoneNumber) {
153         win = window.open("tel://" + phoneNumber);
154         win.close();
155       }
156       return true;
157     },
158     sendMail: function () {
159       var email = this.value ? this.value.get("primaryEmail") : null,
160         win;
161       if (email) {
162         win = window.open("mailto:" + email);
163         win.close();
164       }
165       return true;
166     }
167   });
168
169   // ..........................................................
170   // CUSTOMER
171   //
172
173   enyo.kind({
174     name: "XV.CustomerWidget",
175     kind: "XV.RelationWidget",
176     collection: "XM.CustomerRelationCollection",
177     list: "XV.CustomerList"
178   });
179
180   enyo.kind({
181     name: "XV.BillingCustomerWidget",
182     kind: "XV.RelationWidget",
183     collection: "XM.BillingCustomerCollection",
184     query: { parameters: [{attribute: "isActive", value: true}]},
185     list: "XV.CustomerList"
186   });
187
188   enyo.kind({
189     name: "XV.SalesCustomerWidget",
190     kind: "XV.RelationWidget",
191     collection: "XM.SalesCustomerCollection",
192     list: "XV.CustomerList"
193   });
194
195   // ..........................................................
196   // CUSTOMER GROUP
197   //
198   enyo.kind({
199     name: "XV.CustomerGroupWidget",
200     kind: "XV.RelationWidget",
201     collection: "XM.CustomerGroupCollection",
202     keyAttribute: "name",
203     list: "XV.CustomerGroupList"
204   });
205
206   // ..........................................................
207   // CUSTOMER PROSPECT
208   //
209
210   enyo.kind({
211     name: "XV.CustomerProspectWidget",
212     kind: "XV.RelationWidget",
213     collection: "XM.CustomerProspectRelationCollection",
214     list: "XV.CustomerProspectList",
215     create: function () {
216       var ret = this.inherited(arguments);
217       this.createComponent({
218         kind: "onyx.Popup",
219         name: "customerOrProspectPopup",
220         centered: true,
221         modal: true,
222         floating: true,
223         scrim: true,
224         onShow: "popupShown",
225         onHide: "popupHidden",
226         components: [
227           {content: "_customerOrProspect".loc()},
228           {tag: "br"},
229           {kind: "onyx.Button", name: "customerButton", content: "_customer".loc(), ontap: "popupTapped",
230             classes: "onyx-blue xv-popup-button"},
231           {kind: "onyx.Button", name: "prospectButton", content: "_prospect".loc(), ontap: "popupTapped",
232             classes: "onyx-blue xv-popup-button"}
233         ]
234       });
235       this.$.newItem.setDisabled(false);
236       return ret;
237     },
238     /**
239      @menuItemSelected
240      this overrides the menuItemSelected function of RelationWidget to
241      account for the different types of models presented by the widget.
242      */
243     menuItemSelected: function (inSender, inEvent) {
244       var that = this,
245         menuItem = inEvent.originator,
246         list = this.getList(),
247         model = this.getValue(),
248         K, status, id, workspace,
249         callback;
250
251       switch (menuItem.name)
252       {
253       case "searchItem":
254         callback = function (value) {
255           that.setValue(value);
256         };
257         this.doSearch({
258           list: list,
259           searchText: this.$.input.getValue(),
260           callback: callback
261         });
262         break;
263       case "openItem":
264         K = model.getClass();
265         status = model.get("status");
266         id = model ? model.id : null;
267         workspace = status === K.PROSPECT_STATUS ? "XV.ProspectWorkspace" : "XV.CustomerWorkspace";
268
269         this.doWorkspace({
270           workspace: workspace,
271           id: id,
272           allowNew: false
273         });
274         break;
275       case "newItem":
276         this.$.customerOrProspectPopup.show();
277       }
278     },
279     popupTapped: function (inSender, inEvent) {
280       var that = this,
281         callback = function (model) {
282           if (!model) { return; }
283           var Model = that._collection.model,
284             attrs = {},
285             value,
286             options = {};
287           options.success = function () {
288             that.setValue(value);
289           };
290           attrs[Model.prototype.idAttribute] = model.id;
291           value = Model.findOrCreate(attrs);
292           value.fetch(options);
293         };
294
295       this.$.customerOrProspectPopup.hide();
296       this.doWorkspace({
297         callback: callback,
298         workspace: inEvent.originator.name === "customerButton" ?
299           "XV.CustomerWorkspace" : "XV.ProspectWorkspace",
300         allowNew: false
301       });
302     },
303   });
304
305   // ..........................................................
306   // CUSTOMER SHIPTO
307   //
308
309   enyo.kind({
310     name: "XV.CustomerShiptoWidget",
311     kind: "XV.RelationWidget",
312     collection: "XM.CustomerShiptoRelationCollection",
313     list: "XV.CustomerShiptoList"
314   });
315
316   // ..........................................................
317   // DEPARTMENT
318   //
319
320   enyo.kind({
321     name: "XV.DepartmentWidget",
322     kind: "XV.RelationWidget",
323     collection: "XM.DepartmentCollection",
324     list: "XV.DepartmentList"
325   });
326
327   // ..........................................................
328   // EMPLOYEE
329   //
330
331   enyo.kind({
332     name: "XV.EmployeeWidget",
333     kind: "XV.RelationWidget",
334     collection: "XM.EmployeeRelationCollection",
335     list: "XV.EmployeeList",
336     keyAttribute: "code"
337   });
338
339   // ..........................................................
340   // EXPENSE CATEGORY
341   //
342
343   enyo.kind({
344     name: "XV.ExpenseCategoryWidget",
345     kind: "XV.RelationWidget",
346     collection: "XM.ExpenseCategoryCollection",
347     list: "XV.ExpenseCategoryList",
348     keyAttribute: "code"
349   });
350
351   // ..........................................................
352   // INCIDENT
353   //
354
355   enyo.kind({
356     name: "XV.IncidentWidget",
357     kind: "XV.RelationWidget",
358     collection: "XM.IncidentRelationCollection",
359     list: "XV.IncidentList",
360     nameAttribute: "description"
361   });
362
363   // ..........................................................
364   // ITEM
365   //
366
367   enyo.kind({
368     name: "XV.ItemWidget",
369     kind: "XV.RelationWidget",
370     collection: "XM.ItemRelationCollection",
371     list: "XV.ItemList",
372     nameAttribute: "description1",
373     descripAttribute: "description2"
374   });
375
376   // ..........................................................
377   // LEDGER ACCOUNT
378   //
379
380   enyo.kind({
381     name: "XV.LedgerAccountWidget",
382     kind: "XV.RelationWidget",
383     collection: "XM.LedgerAccountRelationCollection",
384     list: "XV.LedgerAccountList",
385     keyAttribute: "name",
386     nameAttribute: "description"
387   });
388
389   // ..........................................................
390   // OPPORTUNITY
391   //
392
393   enyo.kind({
394     name: "XV.OpportunityWidget",
395     kind: "XV.RelationWidget",
396     collection: "XM.OpportunityRelationCollection",
397     keyAttribute: "name",
398     list: "XV.OpportunityList"
399   });
400
401   // ..........................................................
402   // PROJECT
403   //
404
405   enyo.kind({
406     name: "XV.ProjectWidget",
407     kind: "XV.RelationWidget",
408     collection: "XM.ProjectRelationCollection",
409     list: "XV.ProjectList",
410     create: function () {
411       this.inherited(arguments);
412       this.setShowing(XT.session.settings.get("UseProjects"));
413     },
414     setShowing: function (showing) {
415       if (!showing || showing && XT.session.settings.get("UseProjects")) {
416         this.inherited(arguments);
417       }
418     }
419   });
420
421   // ..........................................................
422   // PURCHASE ORDER
423   //
424
425   enyo.kind({
426     name: "XV.PurchaseOrderWidget",
427     kind: "XV.RelationWidget",
428     collection: "XM.PurchaseOrderRelationCollection",
429     keyAttribute: "number",
430     list: "XV.PurchaseOrderList"
431   });
432
433   // ..........................................................
434   // SALES ORDER
435   //
436
437   enyo.kind({
438     name: "XV.SalesOrderWidget",
439     kind: "XV.RelationWidget",
440     collection: "XM.SalesOrderRelationCollection",
441     keyAttribute: "number",
442     list: "XV.SalesOrderList"
443   });
444
445   // ..........................................................
446   // SHIFT
447   //
448
449   enyo.kind({
450     name: "XV.ShiftWidget",
451     kind: "XV.RelationWidget",
452     collection: "XM.ShiftCollection",
453     list: "XV.ShiftList"
454   });
455
456   // ..........................................................
457   // USER ACCOUNT
458   //
459
460   enyo.kind({
461     name: "XV.UserAccountWidget",
462     classes: "xv-useraccount-widget",
463     kind: "XV.RelationWidget",
464     collection: "XM.UserAccountRelationCollection",
465     list: "XV.UserAccountList",
466     keyAttribute: "username",
467     nameAttribute: "properName"
468   });
469
470   // ..........................................................
471   // VENDOR
472   //
473
474   enyo.kind({
475     name: "XV.VendorWidget",
476     kind: "XV.RelationWidget",
477     collection: "XM.VendorRelationCollection",
478     keyAttribute: "number",
479     list: "XV.VendorList"
480   });
481
482 }());