1 /*jshint bitwise:true, indent:2, curly:true, eqeqeq:true, immed:true,
2 latedef:true, newcap:true, noarg:true, regexp:true, undef:true,
3 trailing:true, white:true, strict: false*/
4 /*global XT:true, XM:true, XV:true, _:true, window: true, enyo:true, Globalize:true*/
8 // ..........................................................
13 An abstract list to be used for email profiles
16 name: "XV.EmailProfileList",
22 {kind: "XV.ListItem", components: [
23 {kind: "FittableColumns", components: [
24 {kind: "XV.ListColumn", classes: "short",
26 {kind: "XV.ListAttr", attr: "name", isKey: true}
28 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
29 {kind: "XV.ListAttr", attr: "description"}
36 // ..........................................................
41 name: "XV.AccountList",
43 label: "_accounts".loc(),
44 collection: "XM.AccountListItemCollection",
48 parameterWidget: "XV.AccountListParameters",
50 {kind: "XV.ListItem", components: [
51 {kind: "FittableColumns", components: [
52 {kind: "XV.ListColumn", classes: "name-column", components: [
53 {kind: "XV.ListAttr", attr: "number", isKey: true},
54 {kind: "XV.ListAttr", attr: "name"}
56 {kind: "XV.ListColumn", classes: "right-column", components: [
57 {kind: "XV.ListAttr", attr: "primaryContact.phone", },
58 {kind: "XV.ListAttr", attr: "primaryContact.primaryEmail"}
60 {kind: "XV.ListColumn", fit: true, components: [
61 {kind: "XV.ListAttr", attr: "primaryContact.name",
62 placeholder: "_noContact".loc()},
63 {kind: "XV.ListAttr", attr: "primaryContact.address"}
70 XV.registerModelList("XM.AccountRelation", "XV.AccountList");
72 // ..........................................................
77 name: "XV.ActivityList",
79 label: "_activities".loc(),
80 collection: "XM.ActivityListItemCollection",
81 parameterWidget: "XV.ActivityListParameters",
86 {name: "reassignUser",
87 method: "reassignUser",
88 prerequisite: "canReassign",
96 {attribute: 'dueDate'},
102 {kind: "XV.ListItem", components: [
103 {kind: "FittableColumns", components: [
104 {kind: "XV.ListColumn", classes: "name-column", components: [
105 {kind: "XV.ListAttr", formatter: "formatName", isKey: true},
106 {kind: "XV.ListAttr", formatter: "formatDescription1"},
108 {kind: "XV.ListColumn", classes: "right-column", components: [
109 {kind: "XV.ListAttr", attr: "dueDate", placeholder: "_noDueDate".loc()},
110 {kind: "XV.ListAttr", attr: "getActivityStatusString"}
112 {kind: "XV.ListColumn", classes: "second",
114 {kind: "XV.ListAttr", attr: "activityType",
115 formatter: "formatType",
116 placeholder: "_noDescription".loc()},
117 {kind: "XV.ListAttr", formatter: "formatDescription2"}
119 {kind: "XV.ListColumn", fit: true, components: [
120 {kind: "XV.ListAttr", attr: "owner.username",
121 placeholder: "_noOwner".loc()},
122 {kind: "XV.ListAttr", attr: "assignedTo.username", name: "assignedTo",
123 placeholder: "_noAssignedTo".loc()}
128 selectedModels: function () {
130 collection = this.getValue(),
133 if (collection.length) {
134 selected = _.keys(this.getSelection().selected);
135 // Using the selected index keys, go grab the models and return them in an array
136 models.push(_.map(selected, function (index) {
137 return that.getModel(index);
142 reassignUser: function () {
143 var callback = function (resp, optionsObj) {
144 var navigator = this.$.navigator;
147 } else if (!resp.componentValue) {
148 navigator.$.contentPanels.getActive().doNotify({
149 type: XM.Model.WARNING,
150 message: "_noUserSelected".loc()
153 // Gather selected models, assemble dispatch params object and send dispatch to server
156 models = optionsObj.models,
157 assignedTo = resp.componentValue.id,
158 ids = _.map(models, function (model) {
161 // Loop through and assemble dispatch param object
162 for (var i = 0; i < ids.length; i++) {
169 // TODO - dispatch error handling
170 options.success = function (resp) {
175 // Send to server with dispath. Need to pass options.error callback for error handling
176 XM.Model.prototype.dispatch("XM.Activity", "reassignUser", params, options);
181 type: XM.Model.QUESTION,
183 message: "_reassignSelectedActivities".loc(),
184 yesLabel: "_reassign".loc(),
185 noLabel: "_cancel".loc(),
186 component: {kind: "XV.UserPicker", name: "assignTo", label: "_assignTo".loc()},
187 options: {models: this.selectedModels()}
190 getWorkspace: function () {
191 if (!this._lastTapIndex) {
192 // don't respond to events waterfalled from other models
195 var collection = this.getValue(),
196 model = collection.at(this._lastTapIndex),
197 recordType = "XM." + model.get("activityType");
198 return XV.getWorkspace(recordType);
200 formatName: function (value, view, model) {
201 var parent = model.get("parent");
202 if (parent) { return parent.get("name"); }
203 return model.get("name");
205 formatDescription1: function (value, view, model) {
206 var parent = model.get("parent");
207 if (parent) { return model.get("name"); }
208 return model.get("description");
210 formatDescription2: function (value, view, model) {
211 var parent = model.get("parent");
212 if (!parent) { return ""; }
213 return model.get("description");
215 formatType: function (value) {
216 return ("_" + value.slice(0, 1).toLowerCase() + value.slice(1)).loc();
218 itemTap: function (inSender, inEvent) {
219 var model = this.getModel(inEvent.index),
220 key = model.get("editorKey"),
222 type = model.get("activityType"),
223 action = model.get("activityAction"),
224 actActions = this.getActivityActions(),
225 actAction = _.find(actActions, function (item) {
226 return item.activityType === type && item.activityAction === action;
230 if (!this.getToggleSelected() || inEvent.originator.isKey) {
231 inEvent.model = model;
232 actAction.method.call(this, inSender, inEvent);
237 this._lastTapIndex = inEvent.index;
238 this.inherited(arguments);
244 // ..........................................................
249 name: "XV.AddressList",
251 label: "_addresses".loc(),
252 collection: "XM.AddressInfoCollection",
254 {attribute: 'country'},
255 {attribute: 'state'},
259 parameterWidget: "XV.AddressListParameters",
261 {kind: "XV.ListItem", components: [
262 {kind: "XV.ListAttr", attr: "id", formatter: "formatAddress",
263 classes: "xv-addresslist-attr", allowHtml: true}
266 formatAddress: function (value, view, model) {
267 return XM.Address.format(model, true);
269 setQuery: function (query) {
270 // If account is in filter, need to switch to a model including account.
273 account = _.find(query.parameters, function (param) {
274 return param.attribute === 'account';
276 collection = account ?
277 'XM.AccountAddressListItemCollection' : 'XM.AddressInfoCollection';
278 this.setCollection(collection);
279 this.inherited(arguments);
283 // ..........................................................
288 name: "XV.BankAccountList",
290 label: "_bankAccounts".loc(),
291 collection: "XM.BankAccountRelationCollection",
296 {kind: "XV.ListItem", components: [
297 {kind: "FittableColumns", components: [
298 {kind: "XV.ListColumn", classes: "short",
300 {kind: "XV.ListAttr", attr: "name", isKey: true}
302 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
303 {kind: "XV.ListAttr", attr: "description"}
310 XV.registerModelList("XM.BankAccountRelation", "XV.BankAccountList");
312 // ..........................................................
317 name: "XV.ClassCodeList",
319 label: "_classCodes".loc(),
320 collection: "XM.ClassCodeCollection",
325 {kind: "XV.ListItem", components: [
326 {kind: "FittableColumns", components: [
327 {kind: "XV.ListColumn", classes: "short",
329 {kind: "XV.ListAttr", attr: "code", isKey: true}
331 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
332 {kind: "XV.ListAttr", attr: "description"}
339 // ..........................................................
344 name: "XV.ConfigurationsList",
346 label: "_configure".loc(),
347 collection: "XM.configurations",
353 {kind: "XV.ListItem", components: [
354 {kind: "FittableColumns", components: [
355 {kind: "XV.ListColumn", classes: "short",
357 {kind: "XV.ListAttr", attr: "name", classes: "bold"}
359 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
360 {kind: "XV.ListAttr", attr: "description"}
365 collectionChanged: function () {
366 var collection = this.getCollection(),
367 obj = XT.getObjectByName(collection);
370 getWorkspace: function () {
371 return this._workspace;
374 Configuration is a special list because it's backed by a backbone
375 model which points to an empty XM.Model in its model attribute. Don't
376 let this go up through the normal channels; handle the opening of
379 itemTap: function (inSender, inEvent) {
380 var model = this.getValue().at(inEvent.index),
381 workspace = model.get("workspace"),
382 xmModel = XT.getObjectByName(model.get('model')),
383 canNotRead = !xmModel.getClass().canRead(),
386 this._workspace = model.get('workspace');
388 // Check privileges first
390 this.showError("_insufficientViewPrivileges".loc());
394 // Bubble requset for workspace view, including the model id payload
396 this.doWorkspace({workspace: workspace, id: id});
406 // ..........................................................
411 name: "XV.ContactList",
413 label: "_contacts".loc(),
414 collection: "XM.ContactListItemCollection",
416 name: "exportContact",
417 method: "vCardExport",
421 {attribute: 'lastName'},
422 {attribute: 'firstName'},
423 {attribute: 'primaryEmail'}
425 parameterWidget: "XV.ContactListParameters",
427 {kind: "XV.ListItem", components: [
428 {kind: "FittableColumns", components: [
429 {kind: "XV.ListColumn", classes: "name-column", components: [
430 {kind: "FittableColumns", components: [
431 {kind: "XV.ListAttr", attr: "firstName",
432 formatter: "formatFirstName", isKey: true},
433 {kind: "XV.ListAttr", attr: "lastName", fit: true,
434 style: "padding-left: 0px;", isKey: true}
436 {kind: "XV.ListAttr", attr: "jobTitle", showPlaceholder: true}
438 {kind: "XV.ListColumn", classes: "right-column", components: [
439 {kind: "XV.ListAttr", attr: "phone"},
440 {kind: "XV.ListAttr", attr: "primaryEmail"}
442 {kind: "XV.ListColumn", fit: true, components: [
443 {kind: "XV.ListAttr", attr: "account.name", showPlaceholder: true},
444 {kind: "XV.ListAttr", attr: "address", showPlaceholder: true}
449 formatFirstName: function (value, view, model) {
450 var lastName = (model.get('lastName') || "").trim(),
451 firstName = (model.get('firstName') || "").trim();
452 if (_.isEmpty(firstName) && _.isEmpty(lastName)) {
453 view.addRemoveClass("placeholder", true);
454 value = "_noName".loc();
456 view.addRemoveClass("bold", _.isEmpty(lastName));
458 if (this.getToggleSelected()) {
459 view.addRemoveClass("hyperlink", true);
463 vCardExport: function (inEvent) {
464 var imodel = inEvent.model,
484 if (model.get('lastName')) {
485 name = model.get('lastName');
486 fullName = model.get('lastName');
488 if (model.get('middleName')) {
489 name = name + ";" + model.get('middleName');
490 fullName = model.get('middleName') + " " + fullName;
492 if (model.get('firstName')) {
493 name = name + ";" + model.get('firstName');
494 fullName = model.get('firstName') + " " + fullName;
500 title = model.get('jobTitle');
501 phoneWork = model.get('phone');
502 phoneHome = model.get('alternate');
503 phoneFax = model.get('fax');
504 if (isNaN(model.getValue('address.line1').charAt(0))) {
505 org = model.getValue('address.line1');
506 address[0] = model.getValue('address.line2');
509 address[0] = model.getValue('address.line1');
510 address.push(model.getValue('address.line2'));
512 address.push(model.getValue('address.line3'));
513 address.push(model.getValue('address.city'));
514 address.push(model.getValue('address.state'));
515 address.push(model.getValue('address.postalCode'));
516 address.push(model.getValue('address.country'));
517 //for address, set address with semicolon delimiters
518 //for label, set address with ESCAPED newline delimiters
520 addressWork = address[0] + ";";
521 labelWork = address[0] + "\\n";
523 for (var i = 1; i < address.length; i++) {
525 addressWork = addressWork + address[i] + ";";
526 labelWork = labelWork + address[i] + "\\n";
529 email = model.get('primaryEmail');
530 website = model.get('webAddress');
531 revision = Globalize.format(new Date(), "yyyy-MM-dd");
534 stringToSave = "BEGIN:" + begin + "%0A";
535 stringToSave = stringToSave + "VERSION:" + version + "%0A";
536 stringToSave = stringToSave + "N:" + name + "%0A";
537 stringToSave = stringToSave + "FN:" + fullName + "%0A";
539 stringToSave = stringToSave + "ORG:" + org + "%0A";
542 stringToSave = stringToSave + "TITLE:" + title + "%0A";
545 stringToSave = stringToSave + "TEL;TYPE=WORK,VOICE:" + phoneWork + "%0A";
548 stringToSave = stringToSave + "TEL;TYPE=HOME,VOICE:" + phoneHome + "%0A";
551 stringToSave = stringToSave + "TEL;TYPE=FAX:" + phoneFax + "%0A";
554 stringToSave = stringToSave + "ADR;TYPE=WORK:;;" + addressWork + "%0A";
557 stringToSave = stringToSave + "LABEL;TYPE=WORK:;;" + labelWork + "%0A";
560 stringToSave = stringToSave + "EMAIL;TYPE=PREF,INTERNET:" + email + "%0A";
563 stringToSave = stringToSave + "URL:" + website + "%0A";
565 stringToSave = stringToSave + "REV:" + revision + "%0A";
566 stringToSave = stringToSave + "END:" + end + "%0A";
568 window.open(XT.getOrganizationPath() +
569 '/%@?stringToSave=%@'
576 XV.registerModelList("XM.ContactRelation", "XV.ContactList");
578 // ..........................................................
583 name: "XV.CostCategoryList",
585 label: "_costCategories".loc(),
586 collection: "XM.CostCategoryCollection",
590 parameterWidget: "XV.CostCategoryListParameters",
592 {kind: "XV.ListItem", components: [
593 {kind: "FittableColumns", components: [
594 {kind: "XV.ListColumn", classes: "short",
596 {kind: "XV.ListAttr", attr: "code", isKey: true}
598 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
599 {kind: "XV.ListAttr", attr: "description"}
606 XV.registerModelList("XM.CostCategory", "XV.CostCategoryList");
608 // ..........................................................
613 name: "XV.CreditCardList",
615 label: "_creditCards".loc(),
616 collection: "XM.CreditCardCollection",
618 {attribute: 'number'}
620 parameterWidget: "XV.CreditCardListParameters",
622 {kind: "XV.ListItem", components: [
623 {kind: "FittableColumns", components: [
624 {kind: "XV.ListColumn", classes: "short",
626 {kind: "XV.ListAttr", attr: "number", isKey: true}
628 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
629 {kind: "XV.ListAttr", attr: "name"}
636 XV.registerModelList("XM.CostCategory", "XV.CostCategoryList");
638 // ..........................................................
643 name: "XV.CurrencyList",
645 label: "_currencies".loc(),
646 collection: "XM.CurrencyCollection",
651 {kind: "XV.ListItem", components: [
652 {kind: "FittableColumns", components: [
653 {kind: "XV.ListColumn", classes: "short",
655 {kind: "XV.ListAttr", attr: "abbreviation", isKey: true}
657 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
658 {kind: "XV.ListAttr", attr: "name"}
660 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
661 {kind: "XV.ListAttr", attr: "isBase"}
668 // ..........................................................
673 name: "XV.CustomerList",
675 label: "_customers".loc(),
676 collection: "XM.CustomerListItemCollection",
678 {attribute: 'number'}
681 parameterWidget: "XV.CustomerListParameters",
683 {kind: "XV.ListItem", components: [
684 {kind: "FittableColumns", components: [
685 {kind: "XV.ListColumn", classes: "name-column", components: [
686 {kind: "XV.ListAttr", attr: "number", isKey: true},
687 {kind: "XV.ListAttr", attr: "name"}
689 {kind: "XV.ListColumn", classes: "right-column", components: [
690 {kind: "XV.ListAttr", attr: "billingContact.phone", },
691 {kind: "XV.ListAttr", attr: "billingContact.primaryEmail"}
693 {kind: "XV.ListColumn", classes: "descr", components: [
694 {kind: "XV.ListAttr", attr: "billingContact.name",
695 placeholder: "_noContact".loc()},
696 {kind: "XV.ListAttr", attr: "billingContact.address"}
698 {kind: "XV.ListColumn", fit: true, components: [
699 {kind: "XV.ListAttr", attr: "customerType.code"}
705 XV.registerModelList("XM.CustomerRelation", "XV.CustomerList");
707 // ..........................................................
708 // CUSTOMER EMAIL PROFILE
711 name: "XV.CustomerEmailProfileList",
712 kind: "XV.EmailProfileList",
713 label: "_customerEmailProfiles".loc(),
714 collection: "XM.CustomerEmailProfileCollection"
717 // ..........................................................
722 name: "XV.CustomerGroupList",
724 label: "_customerGroup".loc(),
725 collection: "XM.CustomerGroupCollection",
726 parameterWidget: "XV.CustomerGroupListParameters",
731 {kind: "XV.ListItem", components: [
732 {kind: "FittableColumns", components: [
733 {kind: "XV.ListColumn", classes: "short",
735 {kind: "XV.ListAttr", attr: "name", isKey: true}
737 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
738 {kind: "XV.ListAttr", attr: "description"}
745 XV.registerModelList("XM.CustomerGroupRelation", "XV.CustomerGroupList");
747 // ..........................................................
752 name: "XV.CustomerProspectList",
753 kind: "XV.CustomerList",
754 label: "_customerProspect".loc(),
755 collection: "XM.CustomerProspectListItemCollection",
757 {kind: "XV.ListItem", components: [
758 {kind: "FittableColumns", components: [
759 {kind: "XV.ListColumn", classes: "name-column", components: [
760 {kind: "XV.ListAttr", attr: "number", isKey: true},
761 {kind: "XV.ListAttr", attr: "name"}
763 {kind: "XV.ListColumn", classes: "right-column", components: [
764 {kind: "XV.ListAttr", attr: "contact.phone", },
765 {kind: "XV.ListAttr", attr: "contact.primaryEmail"}
767 {kind: "XV.ListColumn", fit: true, components: [
768 {kind: "XV.ListAttr", attr: "contact.name",
769 placeholder: "_noContact".loc()},
770 {kind: "XV.ListAttr", attr: "contact.address.formatShort"}
777 XV.registerModelList("XM.CustomerProspectRelation", "XV.CustomerProspectList");
779 // ..........................................................
783 name: "XV.CustomerShiptoList",
785 collection: "XM.CustomerShiptoRelationCollection",
786 parameterWidget: "XV.CustomerShiptoParameters",
791 {kind: "XV.ListItem", components: [
792 {kind: "FittableColumns", components: [
793 {kind: "XV.ListColumn", classes: "short",
795 {kind: "XV.ListAttr", attr: "name", isKey: true}
797 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
798 {kind: "XV.ListAttr", attr: "description"}
804 XV.registerModelList("XM.CustomerShiptoRelation", "XV.CustomerShiptoList");
806 // ..........................................................
807 // CUSTOMER TYPE LIST
811 name: "XV.CustomerTypeList",
813 label: "_customerTypes".loc(),
814 collection: "XM.CustomerTypeCollection",
819 {kind: "XV.ListItem", components: [
820 {kind: "FittableColumns", components: [
821 {kind: "XV.ListColumn", classes: "short",
823 {kind: "XV.ListAttr", attr: "code", isKey: true}
825 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
826 {kind: "XV.ListAttr", attr: "description"}
833 XV.registerModelList("XM.CustomerType", "XV.CustomerTypeList");
835 // ..........................................................
840 name: "XV.DepartmentList",
842 label: "_departments".loc(),
843 collection: "XM.DepartmentCollection",
844 parameterWidget: "XV.DepartmentListParameters",
846 {attribute: 'number'}
849 {kind: "XV.ListItem", components: [
850 {kind: "FittableColumns", components: [
851 {kind: "XV.ListColumn", classes: "short",
853 {kind: "XV.ListAttr", attr: "number", isKey: true}
855 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
856 {kind: "XV.ListAttr", attr: "name"}
863 // ..........................................................
868 name: "XV.EmployeeList",
870 label: "_employees".loc(),
871 collection: "XM.EmployeeRelationCollection",
875 parameterWidget: "XV.EmployeeListParameters",
877 {kind: "XV.ListItem", components: [
878 {kind: "FittableColumns", components: [
879 {kind: "XV.ListColumn", classes: "name-column", components: [
880 {kind: "XV.ListAttr", attr: "code", isKey: true},
881 {kind: "XV.ListAttr", attr: "name"}
883 {kind: "XV.ListColumn", classes: "right-column", components: [
884 {kind: "XV.ListAttr", attr: "contact.phone", },
885 {kind: "XV.ListAttr", attr: "contact.primaryEmail"}
887 {kind: "XV.ListColumn", fit: true, components: [
888 {kind: "XV.ListAttr", attr: "contact.name",
889 placeholder: "_noContact".loc()},
890 {kind: "XV.ListAttr", attr: "contact.address.formatShort"}
897 XV.registerModelList("XM.EmployeeRelation", "XV.EmployeeList");
899 // ..........................................................
904 name: "XV.EmployeeGroupList",
905 kind: "XV.CustomerGroupList",
906 label: "_employeeGroup".loc(),
907 collection: "XM.EmployeeGroupCollection",
908 parameterWidget: "XV.EmployeeGroupListParameters"
911 XV.registerModelList("XM.EmployeeGroupRelation", "XV.EmployeeGroupList");
913 // ..........................................................
918 name: "XV.ExpenseCategoryList",
920 label: "_expenseCategories".loc(),
921 collection: "XM.ExpenseCategoryCollection",
926 {kind: "XV.ListItem", components: [
927 {kind: "FittableColumns", components: [
928 {kind: "XV.ListColumn", classes: "short",
930 {kind: "XV.ListAttr", attr: "code", isKey: true}
932 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
933 {kind: "XV.ListAttr", attr: "description"}
940 // ..........................................................
947 label: "_files".loc(),
948 collection: "XM.FileRelationCollection",
949 parameterWidget: "XV.FileListParameters",
954 {kind: "XV.ListItem", components: [
955 {kind: "FittableColumns", components: [
956 {kind: "XV.ListColumn", classes: "short",
958 {kind: "XV.ListAttr", attr: "name", isKey: true}
960 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
961 {kind: "XV.ListAttr", attr: "description"}
968 XV.registerModelList("XM.FileRelation", "XV.FileList");
970 // ..........................................................
975 name: "XV.FilterList",
977 label: "_filters".loc(),
978 collection: "XM.FilterCollection",
988 {kind: "XV.ListItem", components: [
989 {kind: "FittableColumns", components: [
990 {kind: "XV.ListColumn", classes: "short", fit: true,
992 {kind: "XV.ListAttr", attr: "name"}
994 {kind: "XV.ListColumn", classes: "third", components: [
995 {kind: "XV.ListAttr", attr: "shared", formatter: "formatShared"}
997 {kind: "XV.ListColumn", components: [
998 {tag: "i", classes: "icon-remove list-icon", ontap: "removeRow"}
1000 {kind: "XV.ListColumn", components: [
1001 {tag: "i", classes: "icon-signout list-icon", ontap: "shareRow"}
1007 When the value of the list is changed, bind the add
1008 and remove events of this collection.
1010 valueChanged: function () {
1011 this.inherited(arguments);
1012 // bind enyo event to add/remove on collection of models
1013 this.getValue().on("add", this.doListChange(), this);
1014 this.getValue().on("remove", this.doListChange(), this);
1017 Formatting function to show the shared text instead of
1020 formatShared: function (value, view, model) {
1021 var shared = model && model.get('shared') ? "_shared".loc() : "";
1025 Removes the selected row when the "remove" icon is
1028 removeRow: function (inSender, inEvent) {
1029 var index = inEvent.index,
1030 value = this.getValue(),
1031 model = value.models[index],
1033 inEvent.model = model;
1034 inEvent.done = function () {
1035 inEvent.delete = true;
1036 that.doListChange(inEvent);
1038 this.deleteItem(inEvent);
1041 Sets the shared value of the current model when the
1042 "shared" icon is selected.
1044 shareRow: function (inSender, inEvent) {
1046 index = inEvent.index,
1048 model = this.getValue().models[index];
1049 if (!model.get("shared")) {
1050 model.set("shared", true);
1051 options.success = function (model, resp, options) {
1054 model.save(null, options);
1059 // ..........................................................
1064 name: "XV.FreightClassList",
1066 label: "_freightClass".loc(),
1067 collection: "XM.FreightClassCollection",
1068 parameterWidget: "XV.FreightClassListParameters",
1073 {kind: "XV.ListItem", components: [
1074 {kind: "FittableColumns", components: [
1075 {kind: "XV.ListColumn", classes: "short",
1077 {kind: "XV.ListAttr", attr: "code", isKey: true}
1079 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1080 {kind: "XV.ListAttr", attr: "description"}
1087 XV.registerModelList("XM.FreightClassRelation", "XV.FreightClassList");
1089 // ..........................................................
1094 name: "XV.HonorificList",
1096 label: "_honorifics".loc(),
1097 collection: "XM.HonorificCollection",
1102 {kind: "XV.ListItem", components: [
1103 {kind: "XV.ListColumn", classes: "last", components: [
1104 {kind: "XV.ListAttr", attr: "code", isKey: true}
1110 // ..........................................................
1115 name: "XV.IncidentList",
1117 label: "_incidents".loc(),
1118 collection: "XM.IncidentListItemCollection",
1120 {attribute: 'priorityOrder'},
1121 {attribute: 'updated', descending: true},
1122 {attribute: 'number', descending: true, numeric: true}
1124 toggleSelected: false,
1125 parameterWidget: "XV.IncidentListParameters",
1127 {kind: "XV.ListItem", components: [
1128 {kind: "FittableColumns", components: [
1129 {kind: "XV.ListColumn", classes: "first", components: [
1130 {kind: "FittableColumns", components: [
1131 {kind: "XV.ListAttr", attr: "number", isKey: true},
1132 {kind: "XV.ListAttr", attr: "updated", fit: true,
1133 formatter: "formatDate",
1136 {kind: "XV.ListAttr", attr: "description"}
1138 {kind: "XV.ListColumn", classes: "second", components: [
1139 {kind: "XV.ListAttr", attr: "account.name"},
1140 {kind: "XV.ListAttr", attr: "contact.name"}
1142 {kind: "XV.ListColumn", classes: "third", components: [
1143 {kind: "XV.ListAttr", attr: "getIncidentStatusString"},
1144 {kind: "XV.ListAttr", attr: "assignedTo.username"}
1146 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1147 {kind: "XV.ListAttr", attr: "priority.name",
1148 placeholder: "_noPriority".loc()},
1149 {kind: "XV.ListAttr", attr: "category.name",
1150 placeholder: "_noCategory".loc()}
1155 formatDate: function (value, view, model) {
1156 var date = value ? XT.date.applyTimezoneOffset(value, true) : "",
1157 isToday = date ? !XT.date.compareDate(date, new Date()) : false;
1158 view.addRemoveClass("bold", isToday);
1159 return date ? Globalize.format(date, "d") : "";
1161 getStyle: function (model) {
1162 var settings = XT.session.getSettings(),
1164 status = model ? model.get('status') : null,
1170 background = settings.get('IncidentNewColor');
1173 background = settings.get('IncidentFeedbackColor');
1176 background = settings.get('IncidentConfirmedColor');
1179 background = settings.get('IncidentAssignedColor');
1182 background = settings.get('IncidentResolvedColor');
1185 background = settings.get('IncidentClosedColor');
1189 style = "background: " + background + ";";
1193 setupItem: function (inSender, inEvent) {
1194 this.inherited(arguments);
1195 var model = this.getValue().models[inEvent.index],
1196 style = this.getStyle(model),
1200 // Apply background color to all views.
1201 this.$.listItem.setStyle(style);
1202 for (prop in this.$) {
1203 if (this.$.hasOwnProperty(prop) && this.$[prop].getAttr) {
1204 view = this.$[prop];
1205 view.setStyle(style);
1212 XV.registerModelList("XM.IncidentListItem", "XV.IncidentList");
1213 XV.registerModelList("XM.IncidentRelation", "XV.IncidentList");
1215 // ..........................................................
1216 // INCIDENT EMAIL PROFILE
1220 name: "XV.IncidentEmailProfileList",
1221 kind: "XV.EmailProfileList",
1222 label: "_incidentEmailProfiles".loc(),
1223 collection: "XM.IncidentEmailProfileCollection"
1226 // ..........................................................
1231 name: "XV.InvoiceList",
1234 label: "_invoices".loc(),
1235 parameterWidget: "XV.InvoiceListParameters",
1236 collection: "XM.InvoiceListItemCollection",
1238 {attribute: 'number'}
1241 {name: "void", privilege: "VoidPostedInvoices", prerequisite: "canVoid",
1243 {name: "post", privilege: "PostMiscInvoices", prerequisite: "canPost",
1245 {name: "print", privilege: "PrintInvoices", method: "doPrint", isViewMethod: true },
1246 {name: "email", privilege: "PrintInvoices", method: "doEmail", isViewMethod: true},
1247 {name: "download", privilege: "PrintInvoices", method: "doDownload",
1251 {kind: "XV.ListItem", components: [
1252 {kind: "FittableColumns", components: [
1253 {kind: "XV.ListColumn", classes: "first", components: [
1254 {kind: "FittableColumns", components: [
1255 {kind: "XV.ListAttr", attr: "number", isKey: true, fit: true},
1256 {kind: "XV.ListAttr", attr: "isPosted", fit: true,
1257 formatter: "formatPosted", style: "padding-left: 24px"},
1258 {kind: "XV.ListAttr", name: "dateField", attr: "invoiceDate",
1259 formatter: "formatInvoiceDate", classes: "right",
1260 placeholder: "_noDate".loc()}
1262 {kind: "FittableColumns", components: [
1263 {kind: "XV.ListAttr", attr: "customer.name"},
1264 {kind: "XV.ListAttr", attr: "total", formatter: "formatTotal",
1268 {kind: "XV.ListColumn", classes: "last", components: [
1269 {kind: "XV.ListAttr", formatter: "formatName"},
1270 {kind: "XV.ListAttr", formatter: "formatAddress"}
1275 // some extensions may override this function (i.e. inventory)
1276 formatAddress: function (value, view, model) {
1277 var city = model.get("billtoCity"),
1278 state = model.get("billtoState"),
1279 country = model.get("billtoCountry");
1280 return XM.Address.formatShort(city, state, country);
1282 // some extensions may override this function (i.e. inventory)
1283 formatName: function (value, view, model) {
1284 return model.get("billtoName");
1286 formatPosted: function (value) {
1287 return value ? "_posted".loc() : "_unposted".loc();
1289 formatInvoiceDate: function (value, view, model) {
1290 var isLate = model && !model.get("isPosted") &&
1291 model.get(model.documentDateKey) &&
1292 (XT.date.compareDate(value, new Date()) < 1);
1293 view.addRemoveClass("error", isLate);
1294 return Globalize.format(value, "d");
1296 formatTotal: function (value, view, model) {
1297 var currency = model ? model.get("currency") : false,
1298 scale = XT.locale.moneyScale;
1299 return currency ? currency.format(value, scale) : "";
1302 XV.registerModelList("XM.InvoiceRelation", "XV.InvoiceList");
1304 // ..........................................................
1309 name: "XV.ItemList",
1311 label: "_items".loc(),
1312 collection: "XM.ItemListItemCollection",
1314 {attribute: 'number'}
1316 parameterWidget: "XV.ItemListParameters",
1318 {kind: "XV.ListItem", components: [
1319 {kind: "FittableColumns", components: [
1320 {kind: "XV.ListColumn", classes: "first", components: [
1321 {kind: "FittableColumns", components: [
1322 {kind: "XV.ListAttr", attr: "number", isKey: true},
1323 {kind: "XV.ListAttr", attr: "inventoryUnit.name", fit: true,
1326 {kind: "XV.ListAttr", formatter: "formatDescription"}
1328 {kind: "XV.ListColumn", classes: "second",
1330 {kind: "XV.ListAttr", attr: "formatItemType", classes: "italic"},
1331 {kind: "XV.ListAttr", attr: "classCode.code"}
1333 {kind: "XV.ListColumn", classes: "third", components: [
1334 {kind: "XV.ListAttr", attr: "listPrice", formatter: "formatPrice"},
1335 {kind: "XV.ListAttr", attr: "isFractional", formatter: "formatFractional"}
1337 {kind: "XV.ListColumn", fit: true, components: [
1338 {kind: "XV.ListAttr", attr: "priceUnit.name", formatter: "formatPriceUnit"},
1339 {kind: "XV.ListAttr", attr: "productCategory.code"}
1344 formatFractional: function (value, view, model) {
1345 return value ? "_fractional".loc() : "";
1347 formatPrice: function (value, view, model) {
1348 var sold = model.get("isSold");
1349 if (XT.session.privileges.get("ViewListPrices") && sold) {
1350 var scale = XT.locale.salesPriceScale;
1351 return Globalize.format(value, "c" + scale);
1353 view.addRemoveClass("placeholder", true);
1355 return "_notSold".loc();
1359 formatPriceUnit: function (value, view, model) {
1360 if (XT.session.privileges.get("ViewListPrices") && model.get("isSold")) {
1365 formatDescription: function (value, view, model) {
1366 var descrip1 = model.get("description1") || "",
1367 descrip2 = model.get("description2") || "",
1368 sep = descrip2 ? " - " : "";
1369 return descrip1 + sep + descrip2;
1373 XV.registerModelList("XM.ItemRelation", "XV.ItemList");
1375 // ..........................................................
1380 name: "XV.ItemGroupList",
1382 label: "_itemGroups".loc(),
1383 collection: "XM.ItemGroupRelationCollection",
1388 {kind: "XV.ListItem", components: [
1389 {kind: "FittableColumns", components: [
1390 {kind: "XV.ListColumn", classes: "short",
1392 {kind: "XV.ListAttr", attr: "name", isKey: true}
1394 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1395 {kind: "XV.ListAttr", attr: "description"}
1402 // ..........................................................
1407 name: "XV.ItemSiteList",
1409 label: "_itemSites".loc(),
1410 collection: "XM.ItemSiteListItemCollection",
1412 {attribute: 'item.number'}
1414 parameterWidget: "XV.ItemSiteListParameters",
1416 {kind: "XV.ListItem", components: [
1417 {kind: "FittableColumns", components: [
1418 {kind: "XV.ListColumn", classes: "first", components: [
1419 {kind: "FittableColumns", components: [
1420 {kind: "XV.ListAttr", attr: "item.number", isKey: true},
1421 {kind: "XV.ListAttr", attr: "item.barcode", fit: true, classes: "right"}
1423 {kind: "FittableColumns", components: [
1424 {kind: "XV.ListAttr", attr: "item.description1"},
1425 {kind: "XV.ListAttr", attr: "item.aliases", fit: true,
1426 formatter: "formatAliases", classes: "right"}
1429 {kind: "XV.ListColumn", classes: "second",
1431 {kind: "XV.ListAttr", attr: "site.code", classes: "bold"},
1432 {kind: "XV.ListAttr", attr: "site.description"}
1437 formatActive: function (value, view, model) {
1438 return value ? "_active".loc() : "";
1440 formatAliases: function (value, view, model) {
1441 return value.map(function (model) {
1442 return model.get("aliasNumber");
1445 formatSold: function (value, view, model) {
1446 return value ? "_sold".loc() : "";
1450 XV.registerModelList("XM.ItemSiteRelation", "XV.ItemSiteList");
1452 // ..........................................................
1457 name: "XV.LedgerAccountList",
1459 label: "_ledgerAccounts".loc(),
1460 collection: "XM.LedgerAccountRelationCollection",
1464 parameterWidget: "XV.LedgerAccountListParameters",
1466 {kind: "XV.ListItem", components: [
1467 {kind: "FittableColumns", components: [
1468 {kind: "XV.ListColumn", classes: "first", components: [
1469 {kind: "FittableColumns", components: [
1470 {kind: "XV.ListAttr", attr: "name", isKey: true},
1471 {kind: "XV.ListAttr", attr: "getAccountTypeString", fit: true,
1474 {kind: "XV.ListAttr", attr: "description"}
1476 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1477 {kind: "XV.ListAttr", attr: "externalReference"},
1478 {kind: "XV.ListAttr", attr: "isActive", formatter: "formatActive"}
1483 formatActive: function (value, view, model) {
1484 return value ? "" : "_inactive".loc();
1488 // ..........................................................
1493 name: "XV.OpportunityList",
1495 collection: "XM.OpportunityListItemCollection",
1497 {attribute: 'priorityOrder'},
1498 {attribute: 'targetClose'},
1499 {attribute: 'name'},
1500 {attribute: 'number', numeric: true}
1502 label: "_opportunities".loc(),
1503 parameterWidget: "XV.OpportunityListParameters",
1505 {kind: "XV.ListItem", components: [
1506 {kind: "FittableColumns", components: [
1507 {kind: "XV.ListColumn", classes: "first", components: [
1508 {kind: "FittableColumns", components: [
1509 {kind: "XV.ListAttr", attr: "number", isKey: true},
1510 {kind: "XV.ListAttr", attr: "targetClose", fit: true,
1511 placeholder: "_noCloseTarget".loc(),
1514 {kind: "FittableColumns", components: [
1515 {kind: "XV.ListAttr", attr: "name"},
1516 {kind: "XV.ListAttr", attr: "amount", classes: "right",
1517 formatter: "formatAmount"}
1520 {kind: "XV.ListColumn", classes: "second",
1522 {kind: "XV.ListAttr", attr: "account.name",
1523 placeholder: "_noAccountName".loc()},
1524 {kind: "XV.ListAttr", attr: "contact.name"}
1526 {kind: "XV.ListColumn", classes: "third",
1528 {kind: "XV.ListAttr", attr: "opportunityStage.name",
1529 placeholder: "_noStage".loc()},
1530 {kind: "XV.ListAttr", attr: "assignedTo.username"}
1532 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1533 {kind: "XV.ListAttr", attr: "priority.name",
1534 placeholder: "_noPriority".loc()},
1535 {kind: "XV.ListAttr", attr: "opportunityType.name",
1536 placeholder: "_noType".loc()}
1541 formatAmount: function (value, view, model) {
1542 var currency = model ? model.get("currency") : false,
1543 scale = XT.locale.moneyScale;
1544 return currency ? currency.format(value, scale) : "";
1548 XV.registerModelList("XM.OpportunityListItem", "XV.OpportunityList");
1549 XV.registerModelList("XM.OpportunityRelation", "XV.OpportunityList");
1551 // ..........................................................
1556 name: "XV.PlannerCodeList",
1558 label: "_plannerCodes".loc(),
1559 collection: "XM.PlannerCodeCollection",
1563 parameterWidget: "XV.PlannerCodeListParameters",
1565 {kind: "XV.ListItem", components: [
1566 {kind: "FittableColumns", components: [
1567 {kind: "XV.ListColumn", classes: "first", components: [
1568 {kind: "FittableColumns", components: [
1569 {kind: "XV.ListAttr", attr: "code", isKey: true},
1570 {kind: "XV.ListAttr", attr: "name", fit: true, classes: "right"}
1578 XV.registerModelList("XM.PlannerCode", "XV.PlannerCodeList");
1580 // ..........................................................
1585 name: "XV.ProductCategoryList",
1587 label: "_productCategories".loc(),
1588 collection: "XM.ProductCategoryCollection",
1593 {kind: "XV.ListItem", components: [
1594 {kind: "FittableColumns", components: [
1595 {kind: "XV.ListColumn", classes: "short",
1597 {kind: "XV.ListAttr", attr: "code", isKey: true}
1599 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1600 {kind: "XV.ListAttr", attr: "description"}
1607 // ..........................................................
1612 name: "XV.ProjectList",
1614 label: "_projects".loc(),
1615 collection: "XM.ProjectListItemCollection",
1617 {attribute: "number" }
1619 parameterWidget: "XV.ProjectListParameters",
1621 {kind: "FittableColumns", classes: "xv-list-header",
1623 {kind: "XV.ListColumn", classes: "name-column", components: [
1624 {content: "_name".loc()},
1625 {content: "_description".loc()},
1626 {content: "_account".loc()}
1628 {kind: "XV.ListColumn", classes: "right-column", components: [
1629 {content: "_dueDate".loc()},
1630 {content: "_priority".loc()},
1631 {content: "_complete".loc()}
1633 {kind: "XV.ListColumn", classes: "short", components: [
1634 {content: "_status".loc()},
1635 {content: "_assignedTo".loc()},
1636 {content: "_type".loc()}
1638 {kind: "XV.ListColumn", classes: "right-column"},
1639 {kind: "XV.ListColumn", classes: "right-column", components: [
1640 {content: "_budgeted".loc()},
1641 {content: "_actual".loc()},
1642 {content: "_balance".loc()}
1647 {kind: "XV.ListItem", components: [
1648 {kind: "FittableColumns", components: [
1649 {kind: "XV.ListColumn", classes: "name-column", components: [
1650 {kind: "XV.ListAttr", attr: "number", isKey: true},
1651 {kind: "XV.ListAttr", attr: "name"},
1652 {kind: "XV.ListAttr", attr: "account.name"}
1654 {kind: "XV.ListColumn", classes: "right-column", components: [
1655 {kind: "XV.ListAttr", attr: "dueDate"},
1656 {kind: "XV.ListAttr", attr: "priority.name",
1657 placeholder: "_noPriority".loc()},
1658 {kind: "XV.ListAttr", attr: "percentComplete"}
1660 {kind: "XV.ListColumn", classes: "short",
1662 {kind: "XV.ListAttr", attr: "getProjectStatusString"},
1663 {kind: "XV.ListAttr", attr: "assignedTo.username",
1664 placeholder: "_noAssignedTo".loc()},
1665 {kind: "XV.ListAttr", attr: "projectType.code",
1666 placeholder: "_noProjectType".loc()},
1668 {kind: "XV.ListColumn", classes: "right-column", components: [
1669 {kind: "XV.ListAttr", attr: "budgetedExpenses",
1670 classes: "text-align-right", formatter: "formatExpenses"},
1671 {kind: "XV.ListAttr", attr: "actualExpenses",
1672 classes: "text-align-right", formatter: "formatExpenses"},
1673 {kind: "XV.ListAttr", attr: "balanceExpenses",
1674 classes: "text-align-right", formatter: "formatExpenses"}
1676 {kind: "XV.ListColumn", classes: "right-column", fit: true,
1678 {kind: "XV.ListAttr", attr: "budgetedHours",
1679 classes: "text-align-right", formatter: "formatHours"},
1680 {kind: "XV.ListAttr", attr: "actualHours",
1681 classes: "text-align-right", formatter: "formatHours"},
1682 {kind: "XV.ListAttr", attr: "balanceHours",
1683 classes: "text-align-right", formatter: "formatHours"}
1688 formatHours: function (value, view, model) {
1689 view.addRemoveClass("error", value < 0);
1690 var scale = XT.locale.quantityScale;
1691 return Globalize.format(value, "n" + scale) + " " + "_hrs".loc();
1693 formatExpenses: function (value, view, model) {
1694 view.addRemoveClass("error", value < 0);
1695 var scale = XT.locale.currencyScale;
1696 return Globalize.format(value, "c" + scale);
1701 XV.registerModelList("XM.ProjectListItem", "XV.ProjectList");
1702 XV.registerModelList("XM.ProjectRelation", "XV.ProjectList");
1704 // ..........................................................
1709 name: "XV.ProspectList",
1711 label: "_prospects".loc(),
1712 collection: "XM.ProspectRelationCollection",
1718 method: "convertProspect",
1719 privilege: "MaintainCustomerMasters",
1723 {attribute: 'number'}
1725 parameterWidget: "XV.ProspectListParameters",
1727 {kind: "XV.ListItem", components: [
1728 {kind: "FittableColumns", components: [
1729 {kind: "XV.ListColumn", classes: "first", components: [
1730 {kind: "FittableColumns", components: [
1731 {kind: "XV.ListAttr", attr: "number", isKey: true},
1732 {kind: "XV.ListAttr", attr: "contact.phone", fit: true,
1735 {kind: "FittableColumns", components: [
1736 {kind: "XV.ListAttr", attr: "name"},
1737 {kind: "XV.ListAttr", attr: "contact.primaryEmail", classes: "right"}
1740 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1741 {kind: "XV.ListAttr", attr: "contact.name",
1742 placeholder: "_noContact".loc()},
1743 {kind: "XV.ListAttr", attr: "contact.address"}
1749 Convert the prospect from the list into a customer model. The way we
1750 do this is to open a customer workspace and then call the model method
1751 convertFromProspect AFTER the workspace is initialized. That way
1752 the view and the model get bound together correctly. The user will have
1753 to fill out some customer-specific fields, and when they save a new
1754 customer will be created.
1756 convertProspect: function (inEvent) {
1757 var model = inEvent.model,
1759 success = function () {
1760 this.getValue().convertFromProspect(modelId);
1764 workspace: "XV.CustomerWorkspace",
1766 name: model.get("name"),
1767 number: model.get("number")
1775 XV.registerModelList("XM.ProspectRelation", "XV.ProspectList");
1777 // ..........................................................
1778 // SALES EMAIL PROFILE
1782 name: "XV.SalesEmailProfileList",
1783 kind: "XV.EmailProfileList",
1784 label: "_salesEmailProfiles".loc(),
1785 collection: "XM.SalesEmailProfileCollection"
1788 // ..........................................................
1793 name: "XV.SalesOrderList",
1795 label: "_salesOrders".loc(),
1796 collection: "XM.SalesOrderListItemCollection",
1797 parameterWidget: "XV.SalesOrderListParameters",
1799 {name: "print", privilege: "ViewSalesOrders", method: "doPrint", isViewMethod: true},
1800 {name: "email", privilege: "ViewSalesOrders", method: "doEmail", isViewMethod: true}
1803 {attribute: 'number'}
1806 {kind: "XV.ListItem", components: [
1807 {kind: "FittableColumns", components: [
1808 {kind: "FittableColumns", components: [
1809 {kind: "XV.ListColumn", classes: "name-column", components: [
1810 {kind: "XV.ListAttr", attr: "number", isKey: true},
1811 {kind: "XV.ListAttr", attr: "customer.name"}
1813 {kind: "XV.ListColumn", components: [
1814 {kind: "XV.ListAttr", attr: "formatStatus"}
1816 {kind: "XV.ListColumn", classes: "right-column", components: [
1817 {kind: "XV.ListAttr", attr: "scheduleDate",
1818 placeholder: "_noSchedule".loc()},
1819 {kind: "XV.ListAttr", attr: "total", formatter: "formatTotal"}
1821 {kind: "XV.ListColumn", fit: true, components: [
1822 {kind: "XV.ListAttr", formatter: "formatName"},
1823 {kind: "XV.ListAttr", formatter: "formatShiptoOrBillto"}
1829 formatBillto: function (value, view, model) {
1830 var city = model.get("billtoCity"),
1831 state = model.get("billtoState"),
1832 country = model.get("billtoCountry");
1833 return XM.Address.formatShort(city, state, country);
1836 Returns Shipto Name if one exists, otherwise Billto Name.
1838 formatName: function (value, view, model) {
1839 return model.get("shiptoName") || model.get("billtoName");
1841 formatTotal: function (value, view, model) {
1842 var currency = model ? model.get("currency") : false,
1843 scale = XT.locale.moneyScale;
1844 return currency ? currency.format(value, scale) : "";
1847 formatShipto: function (value, view, model) {
1848 var city = model.get("shiptoCity"),
1849 state = model.get("shiptoState"),
1850 country = model.get("shiptoCountry");
1851 return XM.Address.formatShort(city, state, country);
1854 Returns formatted Shipto City, State and Country if
1855 Shipto Name exists, otherwise Billto location.
1857 formatShiptoOrBillto: function (value, view, model) {
1858 var hasShipto = model.get("shiptoName") ? true : false,
1859 cityAttr = hasShipto ? "shiptoCity": "billtoCity",
1860 stateAttr = hasShipto ? "shiptoState" : "billtoState",
1861 countryAttr = hasShipto ? "shiptoCountry" : "billtoCountry",
1862 city = model.get(cityAttr),
1863 state = model.get(stateAttr),
1864 country = model.get(countryAttr);
1865 return XM.Address.formatShort(city, state, country);
1869 XV.registerModelList("XM.SalesOrderRelation", "XV.SalesOrderList");
1871 // ..........................................................
1876 name: "XV.QuoteList",
1877 kind: "XV.SalesOrderList",
1879 {attribute: 'number'}
1886 method: "convertQuote",
1887 privilege: "ConvertQuotes",
1891 label: "_quotes".loc(),
1892 collection: "XM.QuoteListItemCollection",
1893 parameterWidget: "XV.QuoteListParameters",
1894 formatDate: function (value, view, model) {
1895 var isLate = model && model.get('expireDate') &&
1896 (XT.date.compareDate(value, new Date()) < 1);
1897 view.addRemoveClass("error", isLate);
1900 convertQuote: function (inEvent) {
1901 var model = inEvent.model,
1903 customer = model.get("customer"),
1904 K = XM.CustomerProspectRelation,
1907 // In case we are converting a prospect
1908 convertToCustomer = function (resp) {
1909 if (!resp.answer) { return; }
1912 workspace: "XV.CustomerWorkspace",
1914 number: customer.get("number"),
1915 name: customer.get("name")
1917 success: afterCustomerCreated,
1918 callback: convertToSalesOrder,
1923 afterCustomerCreated = function () {
1924 this.getValue().convertFromProspect(customer.id);
1927 convertToSalesOrder = function () {
1928 XM.SalesOrder.convertFromQuote(model.id, {
1929 success: afterQuoteConvertedSuccess
1933 afterQuoteConvertedSuccess = function (resp) {
1936 workspace: "XV.SalesOrderWorkspace",
1937 success: afterSalesOrderCreated,
1942 afterSalesOrderCreated = function () {
1943 var value = this.getValue(),
1944 gridBox = this.$.salesOrderLineItemBox;
1946 value.setStatus(XM.Model.BUSY_FETCHING);
1948 value.revertStatus();
1950 //Hack to force grid to refresh. Why doesn't it on its own?
1951 gridBox.valueChanged();
1952 gridBox.setDisabled(false);
1956 // Get the process started one way or another
1957 if (customer.get("status") === K.PROSPECT_STATUS) {
1959 type: XM.Model.QUESTION,
1960 callback: convertToCustomer,
1961 message: "_convertProspect".loc()
1964 convertToSalesOrder();
1969 XV.registerModelList("XM.QuoteRelation", "XV.QuoteList");
1971 // ..........................................................
1976 name: "XV.ReasonCodeList",
1978 label: "_reasonCodes".loc(),
1979 collection: "XM.ReasonCodeCollection",
1984 {kind: "XV.ListItem", components: [
1985 {kind: "FittableColumns", components: [
1986 {kind: "XV.ListColumn", classes: "first",
1988 {kind: "XV.ListAttr", attr: "code", isKey: true}
1990 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1991 {kind: "XV.ListAttr", attr: "description"}
1998 // ..........................................................
2003 name: "XV.ReturnList",
2004 kind: "XV.InvoiceList",
2005 label: "_returns".loc(),
2007 parameterWidget: "XV.ReturnListParameters",
2008 collection: "XM.ReturnListItemCollection",
2010 {name: "void", privilege: "VoidPostedARCreditMemos",
2011 prerequisite: "canVoid", method: "doVoid" },
2012 {name: "post", privilege: "PostARDocuments",
2013 prerequisite: "canPost", method: "doPost" },
2014 {name: "print", privilege: "PrintCreditMemos",
2017 create: function () {
2018 this.inherited(arguments);
2019 this.$.dateField.setAttr("returnDate");
2022 XV.registerModelList("XM.ReturnRelation", "XV.ReturnList");
2024 // ..........................................................
2029 name: "XV.SaleTypeList",
2031 label: "_saleTypes".loc(),
2032 collection: "XM.SaleTypeCollection",
2033 parameterWidget: "XV.SaleTypeListParameters",
2038 {kind: "XV.ListItem", components: [
2039 {kind: "FittableColumns", components: [
2040 {kind: "XV.ListColumn", classes: "short",
2042 {kind: "XV.ListAttr", attr: "code", isKey: true}
2044 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2045 {kind: "XV.ListAttr", attr: "description"}
2052 XV.registerModelList("XM.SaleTypeRelation", "XV.SaleTypeList");
2054 // ..........................................................
2059 name: "XV.SalesRepList",
2061 label: "_salesRep".loc(),
2062 collection: "XM.SalesRepCollection",
2063 parameterWidget: "XV.SalesRepListParameters",
2065 {attribute: 'number'}
2068 {kind: "XV.ListItem", components: [
2069 {kind: "FittableColumns", components: [
2070 {kind: "XV.ListColumn", classes: "short",
2072 {kind: "XV.ListAttr", attr: "number", isKey: true}
2074 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2075 {kind: "XV.ListAttr", attr: "name"}
2082 XV.registerModelList("XM.SalesRepRelation", "XV.SalesRepList");
2084 // ..........................................................
2089 name: "XV.SiteList",
2091 label: "_sites".loc(),
2092 collection: "XM.SiteListItemCollection",
2096 parameterWidget: "XV.SiteListParameters",
2098 {kind: "XV.ListItem", components: [
2099 {kind: "FittableColumns", components: [
2100 {kind: "XV.ListColumn", classes: "first", components: [
2101 {kind: "FittableColumns", components: [
2102 {kind: "XV.ListAttr", attr: "code", isKey: true},
2103 {kind: "XV.ListAttr", attr: "description", fit: true, classes: "right"}
2105 {kind: "XV.ListAttr", attr: "siteType.description"}
2112 XV.registerModelList("XM.SiteRelation", "XV.SiteList");
2114 // ..........................................................
2119 name: "XV.ShiftList",
2121 label: "_shifts".loc(),
2122 collection: "XM.ShiftCollection",
2123 parameterWidget: "XV.ShiftListParameters",
2125 {attribute: 'number'}
2128 {kind: "XV.ListItem", components: [
2129 {kind: "FittableColumns", components: [
2130 {kind: "XV.ListColumn", classes: "short",
2132 {kind: "XV.ListAttr", attr: "number", isKey: true}
2134 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2135 {kind: "XV.ListAttr", attr: "name"}
2142 // ..........................................................
2147 name: "XV.ShipViaList",
2149 label: "_shipVias".loc(),
2150 collection: "XM.ShipViaCollection",
2155 {kind: "XV.ListItem", components: [
2156 {kind: "FittableColumns", components: [
2157 {kind: "XV.ListColumn", classes: "short",
2159 {kind: "XV.ListAttr", attr: "code", isKey: true}
2161 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2162 {kind: "XV.ListAttr", attr: "description"}
2168 XV.registerModelList("XM.ShipVia", "XV.ShipViaList");
2170 // ..........................................................
2175 name: "XV.ShipZoneList",
2177 label: "_shipZones".loc(),
2178 collection: "XM.ShipZoneCollection",
2179 parameterWidget: "XV.ShipZoneListParameters",
2184 {kind: "XV.ListItem", components: [
2185 {kind: "FittableColumns", components: [
2186 {kind: "XV.ListColumn", classes: "short",
2188 {kind: "XV.ListAttr", attr: "name", isKey: true}
2190 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2191 {kind: "XV.ListAttr", attr: "description"}
2198 XV.registerModelList("XM.ShipZoneRelation", "XV.ShipZoneList");
2200 // ..........................................................
2205 name: "XV.TaxAssignmentList",
2207 label: "_taxAssignment".loc(),
2208 collection: "XM.TaxAssignmentCollection",
2209 parameterWidget: "XV.TaxAssignmentListParameters",
2214 {kind: "XV.ListItem", components: [
2215 {kind: "FittableColumns", components: [
2216 {kind: "XV.ListColumn", classes: "short", components: [
2217 {kind: "XV.ListAttr", attr: "tax.code", isKey: true}
2219 {kind: "XV.ListColumn", classes: "short", components: [
2220 {kind: "XV.ListAttr", attr: "taxType.name"}
2227 // ..........................................................
2232 name: "XV.TaxAuthorityList",
2234 label: "_taxAuthority".loc(),
2235 collection: "XM.TaxAuthorityCollection",
2236 parameterWidget: "XV.TaxAuthorityListParameters",
2241 {kind: "XV.ListItem", components: [
2242 {kind: "FittableColumns", components: [
2243 {kind: "XV.ListColumn", classes: "short",
2245 {kind: "XV.ListAttr", attr: "code", isKey: true}
2247 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2248 {kind: "XV.ListAttr", attr: "name"}
2255 // ..........................................................
2260 name: "XV.TaxCodeList",
2262 label: "_taxCode".loc(),
2263 collection: "XM.TaxCodeCollection",
2264 parameterWidget: "XV.TaxCodeListParameters",
2269 {kind: "XV.ListItem", components: [
2270 {kind: "FittableColumns", components: [
2271 {kind: "XV.ListColumn", classes: "short",
2273 {kind: "XV.ListAttr", attr: "code", isKey: true}
2275 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2276 {kind: "XV.ListAttr", attr: "description"}
2283 XV.registerModelList("XM.TaxCodeRelation", "XV.TaxCodeList");
2285 // ..........................................................
2290 name: "XV.TaxClassList",
2292 label: "_taxClass".loc(),
2293 collection: "XM.TaxClassCollection",
2294 parameterWidget: "XV.TaxClassListParameters",
2299 {kind: "XV.ListItem", components: [
2300 {kind: "FittableColumns", components: [
2301 {kind: "XV.ListColumn", classes: "short",
2303 {kind: "XV.ListAttr", attr: "code", isKey: true}
2305 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2306 {kind: "XV.ListAttr", attr: "description"}
2313 XV.registerModelList("XM.TaxClassRelation", "XV.TaxClassList");
2315 // ..........................................................
2320 name: "XV.TaxRateList",
2322 label: "_taxRate".loc(),
2323 collection: "XM.TaxRateCollection",
2324 parameterWidget: "XV.TaxRateListParameters",
2329 {kind: "XV.ListItem", components: [
2330 {kind: "FittableColumns", components: [
2331 {kind: "XV.ListColumn", classes: "short", components: [
2332 {kind: "XV.ListAttr", attr: "tax.code", isKey: true}
2334 {kind: "XV.ListColumn", classes: "short", components: [
2335 {kind: "XV.ListAttr", attr: "percent"}
2342 // ..........................................................
2347 name: "XV.TaxTypeList",
2349 label: "_taxType".loc(),
2350 collection: "XM.TaxTypeCollection",
2351 parameterWidget: "XV.TaxTypeListParameters",
2356 {kind: "XV.ListItem", components: [
2357 {kind: "FittableColumns", components: [
2358 {kind: "XV.ListColumn", classes: "short",
2360 {kind: "XV.ListAttr", attr: "name", isKey: true}
2362 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2363 {kind: "XV.ListAttr", attr: "description"}
2370 XV.registerModelList("XM.TaxTypeRelation", "XV.TaxTypeList");
2372 // ..........................................................
2377 name: "XV.TaxZoneList",
2379 label: "_taxZone".loc(),
2380 collection: "XM.TaxZoneCollection",
2381 parameterWidget: "XV.TaxZoneListParameters",
2386 {kind: "XV.ListItem", components: [
2387 {kind: "FittableColumns", components: [
2388 {kind: "XV.ListColumn", classes: "short",
2390 {kind: "XV.ListAttr", attr: "code", isKey: true}
2392 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2393 {kind: "XV.ListAttr", attr: "description"}
2400 XV.registerModelList("XM.TaxZoneRelation", "XV.TaxZoneList");
2402 // ..........................................................
2407 name: "XV.TermsList",
2409 label: "_terms".loc(),
2410 collection: "XM.TermsCollection",
2411 parameterWidget: "XV.TermsListParameters",
2416 {kind: "XV.ListItem", components: [
2417 {kind: "FittableColumns", components: [
2418 {kind: "XV.ListColumn", classes: "short",
2420 {kind: "XV.ListAttr", attr: "code", isKey: true}
2422 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2423 {kind: "XV.ListAttr", attr: "description"}
2430 XV.registerModelList("XM.TermsRelation", "XV.TermsList");
2432 // ..........................................................
2437 name: "XV.ToDoList",
2439 label: "_toDo".loc(),
2440 collection: "XM.ToDoListItemCollection",
2441 parameterWidget: "XV.ToDoListParameters",
2443 {attribute: 'priorityOrder'},
2444 {attribute: 'dueDate'},
2448 {kind: "XV.ListItem", components: [
2449 {kind: "FittableColumns", components: [
2450 {kind: "XV.ListColumn", classes: "first", components: [
2451 {kind: "FittableColumns", components: [
2452 {kind: "XV.ListAttr", attr: "name", isKey: true},
2453 {kind: "XV.ListAttr", attr: "dueDate", fit: true,
2454 placeholder: "_noDueDate".loc(), classes: "right"}
2456 {kind: "XV.ListAttr", attr: "description",
2457 placeholder: "_noDescription".loc()}
2459 {kind: "XV.ListColumn", classes: "second",
2461 {kind: "XV.ListAttr", attr: "account.name",
2462 placeholder: "_noAccountName".loc()},
2463 {kind: "XV.ListAttr", attr: "contact.name"}
2465 {kind: "XV.ListColumn", classes: "third",
2467 {kind: "XV.ListAttr", attr: "getToDoStatusString"},
2468 {kind: "XV.ListAttr", attr: "owner.username"}
2470 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2471 {kind: "XV.ListAttr", attr: "priority.name",
2472 placeholder: "_noPriority".loc()}
2479 XV.registerModelList("XM.ToDoRelation", "XV.ToDoList");
2481 // ..........................................................
2488 label: "_urls".loc(),
2489 collection: "XM.UrlCollection",
2490 parameterWidget: "XV.UrlListParameters",
2495 {kind: "XV.ListItem", components: [
2496 {kind: "FittableColumns", components: [
2497 {kind: "XV.ListColumn", classes: "short",
2499 {kind: "XV.ListAttr", attr: "name", isKey: true}
2501 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2502 {kind: "XV.ListAttr", attr: "path"}
2509 XV.registerModelList("XM.Url", "XV.UrlList");
2511 // ..........................................................
2516 name: "XV.UserAccountList",
2518 label: "_userAccounts".loc(),
2519 collection: "XM.UserAccountRelationCollection",
2520 parameterWidget: "XV.UserAccountListParameters",
2522 {attribute: 'username'}
2525 {kind: "XV.ListItem", components: [
2526 {kind: "FittableColumns", components: [
2527 {kind: "XV.ListColumn", classes: "short", components: [
2528 {kind: "XV.ListAttr", attr: "username", isKey: true}
2530 {kind: "XV.ListColumn", classes: "short", components: [
2531 {kind: "XV.ListAttr", attr: "propername"}
2538 XV.registerModelList("XM.UserAccountRelation", "XV.UserAccountList");
2540 // ..........................................................
2541 // STATES AND COUNTRIES
2545 name: "XV.AbbreviationList",
2548 {kind: "XV.ListItem", components: [
2549 {kind: "FittableColumns", components: [
2550 {kind: "XV.ListColumn", classes: "short",
2552 {kind: "XV.ListAttr", attr: "abbreviation", isKey: true}
2554 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2555 {kind: "XV.ListAttr", attr: "name"}
2563 name: "XV.StateList",
2564 kind: "XV.AbbreviationList",
2565 label: "_states".loc(),
2566 collection: "XM.StateCollection",
2567 query: {orderBy: [{ attribute: 'abbreviation' }] }
2571 name: "XV.CountryList",
2572 kind: "XV.AbbreviationList",
2573 label: "_countries".loc(),
2574 collection: "XM.CountryCollection",
2576 {attribute: 'abbreviation'}
2580 // ..........................................................
2585 name: "XV.VendorList",
2587 label: "_vendors".loc(),
2588 collection: "XM.VendorListItemCollection",
2590 {attribute: 'number'}
2592 parameterWidget: "XV.VendorListParameters",
2594 {kind: "XV.ListItem", components: [
2595 {kind: "FittableColumns", components: [
2596 {kind: "XV.ListColumn", classes: "first", components: [
2597 {kind: "FittableColumns", components: [
2598 {kind: "XV.ListAttr", attr: "number", isKey: true},
2599 {kind: "XV.ListAttr", attr: "primaryContact.phone", fit: true,
2602 {kind: "FittableColumns", components: [
2603 {kind: "XV.ListAttr", attr: "name"},
2604 {kind: "XV.ListAttr", attr: "primaryContact.primaryEmail", classes: "right"}
2607 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2608 {kind: "XV.ListAttr", attr: "primaryContact.name",
2609 placeholder: "_noContact".loc()},
2610 {kind: "XV.ListAttr", attr: "address"}
2617 XV.registerModelList("XM.VendorRelation", "XV.VendorList");
2619 // ..........................................................
2624 name: "XV.VendorAddressList",
2626 collection: "XM.VendorAddressRelationCollection",
2627 parameterWidget: "XV.VendorAddressParameters",
2632 {kind: "XV.ListItem", components: [
2633 {kind: "FittableColumns", components: [
2634 {kind: "XV.ListColumn", classes: "short",
2636 {kind: "XV.ListAttr", attr: "code", isKey: true}
2638 {kind: "XV.ListColumn", fit: true, components: [
2639 {kind: "XV.ListAttr", attr: "name"},
2640 {kind: "XV.ListAttr", formatter: "formatAddress",
2641 classes: "xv-addresslist-attr", allowHtml: true}
2646 formatAddress: function (value, view, model) {
2647 var address = model.get("address");
2648 return address.format(true);
2652 XV.registerModelList("XM.VendarAddressRelation", "XV.VendorAddressList");
2655 name: "XV.NameList",
2661 {kind: "XV.ListItem", components: [
2662 {kind: "FittableColumns", components: [
2663 {kind: "XV.ListColumn", classes: "first",
2665 {kind: "XV.ListAttr", attr: "name", isKey: true}
2671 All of these lists follow a very similar naming convention.
2672 Apply that convention unless the list overrides the label
2673 or collection attribute.
2675 create: function () {
2676 var kindName = this.kind.substring(0, this.kind.length - 4).substring(3);
2677 if (!this.getLabel()) {
2678 this.setLabel(this.determineLabel(kindName));
2680 if (!this.getCollection()) {
2681 this.setCollection("XM." + kindName + "Collection");
2683 this.inherited(arguments);
2686 determineLabel: function (kindName) {
2687 return ("_" + kindName.camelize().pluralize()).loc();
2691 // ..........................................................
2692 // INCIDENT CATEGORIES, RESOLUTIONS, SEVERITIES,
2694 // OPPORTUNITY SOURCES, STAGES, TYPES,
2696 // Basically anything whose rows are name and description
2699 name: "XV.NameDescriptionList",
2700 kind: "XV.NameList",
2702 {kind: "XV.ListItem", components: [
2703 {kind: "FittableColumns", components: [
2704 {kind: "XV.ListColumn", classes: "short",
2706 {kind: "XV.ListAttr", attr: "name", isKey: true}
2708 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2709 {kind: "XV.ListAttr", attr: "description"}
2717 name: "XV.IncidentCategoryList",
2718 kind: "XV.NameDescriptionList"
2722 name: "XV.IncidentResolutionList",
2723 kind: "XV.NameDescriptionList"
2727 name: "XV.IncidentSeverityList",
2728 kind: "XV.NameDescriptionList"
2732 name: "XV.PriorityList",
2733 kind: "XV.NameDescriptionList"
2737 name: "XV.UnitList",
2738 kind: "XV.NameDescriptionList"
2742 name: "XV.OpportunitySourceList",
2743 kind: "XV.NameDescriptionList",
2745 query: {orderBy: [{ attribute: 'name' }] }
2750 name: "XV.OpportunityStageList",
2751 kind: "XV.NameDescriptionList",
2753 query: {orderBy: [{ attribute: 'name' }] }
2758 name: "XV.OpportunityTypeList",
2759 kind: "XV.NameDescriptionList",
2761 query: {orderBy: [{ attribute: 'name' }] }
2766 name: "XV.SiteTypeList",
2767 kind: "XV.NameDescriptionList",
2768 collection: "XM.SiteTypeCollection"
2772 name: "XV.UserAccountRoleList",
2773 kind: "XV.NameDescriptionList",
2774 collection: "XM.UserAccountRoleListItemCollection"
2778 name: "XV.CharacteristicList",
2779 kind: "XV.NameList",
2780 collection: "XM.CharacteristicCollection"