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", fit: true, components: [
694 {kind: "XV.ListAttr", attr: "billingContact.name",
695 placeholder: "_noContact".loc()},
696 {kind: "XV.ListAttr", attr: "billingContact.address"}
702 XV.registerModelList("XM.CustomerRelation", "XV.CustomerList");
704 // ..........................................................
705 // CUSTOMER EMAIL PROFILE
708 name: "XV.CustomerEmailProfileList",
709 kind: "XV.EmailProfileList",
710 label: "_customerEmailProfiles".loc(),
711 collection: "XM.CustomerEmailProfileCollection"
714 // ..........................................................
719 name: "XV.CustomerGroupList",
721 label: "_customerGroup".loc(),
722 collection: "XM.CustomerGroupCollection",
723 parameterWidget: "XV.CustomerGroupListParameters",
728 {kind: "XV.ListItem", components: [
729 {kind: "FittableColumns", components: [
730 {kind: "XV.ListColumn", classes: "short",
732 {kind: "XV.ListAttr", attr: "name", isKey: true}
734 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
735 {kind: "XV.ListAttr", attr: "description"}
742 XV.registerModelList("XM.CustomerGroupRelation", "XV.CustomerGroupList");
744 // ..........................................................
749 name: "XV.CustomerProspectList",
750 kind: "XV.CustomerList",
751 label: "_customerProspect".loc(),
752 collection: "XM.CustomerProspectListItemCollection",
754 {kind: "XV.ListItem", components: [
755 {kind: "FittableColumns", components: [
756 {kind: "XV.ListColumn", classes: "name-column", components: [
757 {kind: "XV.ListAttr", attr: "number", isKey: true},
758 {kind: "XV.ListAttr", attr: "name"}
760 {kind: "XV.ListColumn", classes: "right-column", components: [
761 {kind: "XV.ListAttr", attr: "contact.phone", },
762 {kind: "XV.ListAttr", attr: "contact.primaryEmail"}
764 {kind: "XV.ListColumn", fit: true, components: [
765 {kind: "XV.ListAttr", attr: "contact.name",
766 placeholder: "_noContact".loc()},
767 {kind: "XV.ListAttr", attr: "contact.address.formatShort"}
774 XV.registerModelList("XM.CustomerProspectRelation", "XV.CustomerProspectList");
776 // ..........................................................
780 name: "XV.CustomerShiptoList",
782 collection: "XM.CustomerShiptoRelationCollection",
783 parameterWidget: "XV.CustomerShiptoParameters",
788 {kind: "XV.ListItem", components: [
789 {kind: "FittableColumns", components: [
790 {kind: "XV.ListColumn", classes: "short",
792 {kind: "XV.ListAttr", attr: "name", isKey: true}
794 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
795 {kind: "XV.ListAttr", attr: "description"}
801 XV.registerModelList("XM.CustomerShiptoRelation", "XV.CustomerShiptoList");
803 // ..........................................................
804 // CUSTOMER TYPE LIST
808 name: "XV.CustomerTypeList",
810 label: "_customerTypes".loc(),
811 collection: "XM.CustomerTypeCollection",
816 {kind: "XV.ListItem", components: [
817 {kind: "FittableColumns", components: [
818 {kind: "XV.ListColumn", classes: "short",
820 {kind: "XV.ListAttr", attr: "code", isKey: true}
822 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
823 {kind: "XV.ListAttr", attr: "description"}
830 XV.registerModelList("XM.CustomerType", "XV.CustomerTypeList");
832 // ..........................................................
837 name: "XV.DepartmentList",
839 label: "_departments".loc(),
840 collection: "XM.DepartmentCollection",
841 parameterWidget: "XV.DepartmentListParameters",
843 {attribute: 'number'}
846 {kind: "XV.ListItem", components: [
847 {kind: "FittableColumns", components: [
848 {kind: "XV.ListColumn", classes: "short",
850 {kind: "XV.ListAttr", attr: "number", isKey: true}
852 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
853 {kind: "XV.ListAttr", attr: "name"}
860 // ..........................................................
865 name: "XV.EmployeeList",
867 label: "_employees".loc(),
868 collection: "XM.EmployeeRelationCollection",
872 parameterWidget: "XV.EmployeeListParameters",
874 {kind: "XV.ListItem", components: [
875 {kind: "FittableColumns", components: [
876 {kind: "XV.ListColumn", classes: "name-column", components: [
877 {kind: "XV.ListAttr", attr: "code", isKey: true},
878 {kind: "XV.ListAttr", attr: "name"}
880 {kind: "XV.ListColumn", classes: "right-column", components: [
881 {kind: "XV.ListAttr", attr: "contact.phone", },
882 {kind: "XV.ListAttr", attr: "contact.primaryEmail"}
884 {kind: "XV.ListColumn", fit: true, components: [
885 {kind: "XV.ListAttr", attr: "contact.name",
886 placeholder: "_noContact".loc()},
887 {kind: "XV.ListAttr", attr: "contact.address.formatShort"}
894 XV.registerModelList("XM.EmployeeRelation", "XV.EmployeeList");
896 // ..........................................................
901 name: "XV.EmployeeGroupList",
902 kind: "XV.CustomerGroupList",
903 label: "_employeeGroup".loc(),
904 collection: "XM.EmployeeGroupCollection",
905 parameterWidget: "XV.EmployeeGroupListParameters"
908 XV.registerModelList("XM.EmployeeGroupRelation", "XV.EmployeeGroupList");
910 // ..........................................................
915 name: "XV.ExpenseCategoryList",
917 label: "_expenseCategories".loc(),
918 collection: "XM.ExpenseCategoryCollection",
923 {kind: "XV.ListItem", components: [
924 {kind: "FittableColumns", components: [
925 {kind: "XV.ListColumn", classes: "short",
927 {kind: "XV.ListAttr", attr: "code", isKey: true}
929 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
930 {kind: "XV.ListAttr", attr: "description"}
937 // ..........................................................
944 label: "_files".loc(),
945 collection: "XM.FileRelationCollection",
946 parameterWidget: "XV.FileListParameters",
951 {kind: "XV.ListItem", components: [
952 {kind: "FittableColumns", components: [
953 {kind: "XV.ListColumn", classes: "short",
955 {kind: "XV.ListAttr", attr: "name", isKey: true}
957 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
958 {kind: "XV.ListAttr", attr: "description"}
965 XV.registerModelList("XM.FileRelation", "XV.FileList");
967 // ..........................................................
972 name: "XV.FilterList",
974 label: "_filters".loc(),
975 collection: "XM.FilterCollection",
985 {kind: "XV.ListItem", components: [
986 {kind: "FittableColumns", components: [
987 {kind: "XV.ListColumn", classes: "short", fit: true,
989 {kind: "XV.ListAttr", attr: "name"}
991 {kind: "XV.ListColumn", classes: "third", components: [
992 {kind: "XV.ListAttr", attr: "shared", formatter: "formatShared"}
994 {kind: "XV.ListColumn", components: [
995 {tag: "i", classes: "icon-remove list-icon", ontap: "removeRow"}
997 {kind: "XV.ListColumn", components: [
998 {tag: "i", classes: "icon-signout list-icon", ontap: "shareRow"}
1004 When the value of the list is changed, bind the add
1005 and remove events of this collection.
1007 valueChanged: function () {
1008 this.inherited(arguments);
1009 // bind enyo event to add/remove on collection of models
1010 this.getValue().on("add", this.doListChange(), this);
1011 this.getValue().on("remove", this.doListChange(), this);
1014 Formatting function to show the shared text instead of
1017 formatShared: function (value, view, model) {
1018 var shared = model && model.get('shared') ? "_shared".loc() : "";
1022 Removes the selected row when the "remove" icon is
1025 removeRow: function (inSender, inEvent) {
1026 var index = inEvent.index,
1027 value = this.getValue(),
1028 model = value.models[index],
1030 inEvent.model = model;
1031 inEvent.done = function () {
1032 inEvent.delete = true;
1033 that.doListChange(inEvent);
1035 this.deleteItem(inEvent);
1038 Sets the shared value of the current model when the
1039 "shared" icon is selected.
1041 shareRow: function (inSender, inEvent) {
1043 index = inEvent.index,
1045 model = this.getValue().models[index];
1046 if (!model.get("shared")) {
1047 model.set("shared", true);
1048 options.success = function (model, resp, options) {
1051 model.save(null, options);
1056 // ..........................................................
1061 name: "XV.FreightClassList",
1063 label: "_freightClass".loc(),
1064 collection: "XM.FreightClassCollection",
1065 parameterWidget: "XV.FreightClassListParameters",
1070 {kind: "XV.ListItem", components: [
1071 {kind: "FittableColumns", components: [
1072 {kind: "XV.ListColumn", classes: "short",
1074 {kind: "XV.ListAttr", attr: "code", isKey: true}
1076 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1077 {kind: "XV.ListAttr", attr: "description"}
1084 XV.registerModelList("XM.FreightClassRelation", "XV.FreightClassList");
1086 // ..........................................................
1091 name: "XV.HonorificList",
1093 label: "_honorifics".loc(),
1094 collection: "XM.HonorificCollection",
1099 {kind: "XV.ListItem", components: [
1100 {kind: "XV.ListColumn", classes: "last", components: [
1101 {kind: "XV.ListAttr", attr: "code", isKey: true}
1107 // ..........................................................
1112 name: "XV.IncidentList",
1114 label: "_incidents".loc(),
1115 collection: "XM.IncidentListItemCollection",
1117 {attribute: 'priorityOrder'},
1118 {attribute: 'updated', descending: true},
1119 {attribute: 'number', descending: true, numeric: true}
1121 toggleSelected: false,
1122 parameterWidget: "XV.IncidentListParameters",
1124 {kind: "XV.ListItem", components: [
1125 {kind: "FittableColumns", components: [
1126 {kind: "XV.ListColumn", classes: "first", components: [
1127 {kind: "FittableColumns", components: [
1128 {kind: "XV.ListAttr", attr: "number", isKey: true},
1129 {kind: "XV.ListAttr", attr: "updated", fit: true,
1130 formatter: "formatDate",
1133 {kind: "XV.ListAttr", attr: "description"}
1135 {kind: "XV.ListColumn", classes: "second", components: [
1136 {kind: "XV.ListAttr", attr: "account.name"},
1137 {kind: "XV.ListAttr", attr: "contact.name"}
1139 {kind: "XV.ListColumn", classes: "third", components: [
1140 {kind: "XV.ListAttr", attr: "getIncidentStatusString"},
1141 {kind: "XV.ListAttr", attr: "assignedTo.username"}
1143 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1144 {kind: "XV.ListAttr", attr: "priority.name",
1145 placeholder: "_noPriority".loc()},
1146 {kind: "XV.ListAttr", attr: "category.name",
1147 placeholder: "_noCategory".loc()}
1152 formatDate: function (value, view, model) {
1153 var date = value ? XT.date.applyTimezoneOffset(value, true) : "",
1154 isToday = date ? !XT.date.compareDate(date, new Date()) : false;
1155 view.addRemoveClass("bold", isToday);
1156 return date ? Globalize.format(date, "d") : "";
1158 getStyle: function (model) {
1159 var settings = XT.session.getSettings(),
1161 status = model ? model.get('status') : null,
1167 background = settings.get('IncidentNewColor');
1170 background = settings.get('IncidentFeedbackColor');
1173 background = settings.get('IncidentConfirmedColor');
1176 background = settings.get('IncidentAssignedColor');
1179 background = settings.get('IncidentResolvedColor');
1182 background = settings.get('IncidentClosedColor');
1186 style = "background: " + background + ";";
1190 setupItem: function (inSender, inEvent) {
1191 this.inherited(arguments);
1192 var model = this.getValue().models[inEvent.index],
1193 style = this.getStyle(model),
1197 // Apply background color to all views.
1198 this.$.listItem.setStyle(style);
1199 for (prop in this.$) {
1200 if (this.$.hasOwnProperty(prop) && this.$[prop].getAttr) {
1201 view = this.$[prop];
1202 view.setStyle(style);
1209 XV.registerModelList("XM.IncidentListItem", "XV.IncidentList");
1210 XV.registerModelList("XM.IncidentRelation", "XV.IncidentList");
1212 // ..........................................................
1213 // INCIDENT EMAIL PROFILE
1217 name: "XV.IncidentEmailProfileList",
1218 kind: "XV.EmailProfileList",
1219 label: "_incidentEmailProfiles".loc(),
1220 collection: "XM.IncidentEmailProfileCollection"
1223 // ..........................................................
1228 name: "XV.InvoiceList",
1231 label: "_invoices".loc(),
1232 parameterWidget: "XV.InvoiceListParameters",
1233 collection: "XM.InvoiceListItemCollection",
1235 {attribute: 'number'}
1238 {name: "void", privilege: "VoidPostedInvoices", prerequisite: "canVoid",
1240 {name: "post", privilege: "PostMiscInvoices", prerequisite: "canPost",
1242 {name: "print", privilege: "PrintInvoices", method: "doPrint", isViewMethod: true },
1243 {name: "email", privilege: "PrintInvoices", method: "doEmail", isViewMethod: true},
1244 {name: "download", privilege: "PrintInvoices", method: "doDownload",
1248 {kind: "XV.ListItem", components: [
1249 {kind: "FittableColumns", components: [
1250 {kind: "XV.ListColumn", classes: "first", components: [
1251 {kind: "FittableColumns", components: [
1252 {kind: "XV.ListAttr", attr: "number", isKey: true, fit: true},
1253 {kind: "XV.ListAttr", attr: "isPosted", fit: true,
1254 formatter: "formatPosted", style: "padding-left: 24px"},
1255 {kind: "XV.ListAttr", name: "dateField", attr: "invoiceDate",
1256 formatter: "formatInvoiceDate", classes: "right",
1257 placeholder: "_noDate".loc()}
1259 {kind: "FittableColumns", components: [
1260 {kind: "XV.ListAttr", attr: "customer.name"},
1261 {kind: "XV.ListAttr", attr: "total", formatter: "formatTotal",
1265 {kind: "XV.ListColumn", classes: "last", components: [
1266 {kind: "XV.ListAttr", formatter: "formatName"},
1267 {kind: "XV.ListAttr", formatter: "formatAddress"}
1272 // some extensions may override this function (i.e. inventory)
1273 formatAddress: function (value, view, model) {
1274 var city = model.get("billtoCity"),
1275 state = model.get("billtoState"),
1276 country = model.get("billtoCountry");
1277 return XM.Address.formatShort(city, state, country);
1279 // some extensions may override this function (i.e. inventory)
1280 formatName: function (value, view, model) {
1281 return model.get("billtoName");
1283 formatPosted: function (value) {
1284 return value ? "_posted".loc() : "_unposted".loc();
1286 formatInvoiceDate: function (value, view, model) {
1287 var isLate = model && !model.get("isPosted") &&
1288 model.get(model.documentDateKey) &&
1289 (XT.date.compareDate(value, new Date()) < 1);
1290 view.addRemoveClass("error", isLate);
1291 return Globalize.format(value, "d");
1293 formatTotal: function (value, view, model) {
1294 var currency = model ? model.get("currency") : false,
1295 scale = XT.locale.moneyScale;
1296 return currency ? currency.format(value, scale) : "";
1299 XV.registerModelList("XM.InvoiceRelation", "XV.InvoiceList");
1301 // ..........................................................
1306 name: "XV.ItemList",
1308 label: "_items".loc(),
1309 collection: "XM.ItemListItemCollection",
1311 {attribute: 'number'}
1313 parameterWidget: "XV.ItemListParameters",
1315 {kind: "XV.ListItem", components: [
1316 {kind: "FittableColumns", components: [
1317 {kind: "XV.ListColumn", classes: "first", components: [
1318 {kind: "FittableColumns", components: [
1319 {kind: "XV.ListAttr", attr: "number", isKey: true},
1320 {kind: "XV.ListAttr", attr: "inventoryUnit.name", fit: true,
1323 {kind: "XV.ListAttr", formatter: "formatDescription"}
1325 {kind: "XV.ListColumn", classes: "second",
1327 {kind: "XV.ListAttr", attr: "formatItemType", classes: "italic"},
1328 {kind: "XV.ListAttr", attr: "classCode.code"}
1330 {kind: "XV.ListColumn", classes: "third", components: [
1331 {kind: "XV.ListAttr", attr: "listPrice", formatter: "formatPrice"},
1332 {kind: "XV.ListAttr", attr: "isFractional", formatter: "formatFractional"}
1334 {kind: "XV.ListColumn", fit: true, components: [
1335 {kind: "XV.ListAttr", attr: "priceUnit.name", formatter: "formatPriceUnit"},
1336 {kind: "XV.ListAttr", attr: "productCategory.code"}
1341 formatFractional: function (value, view, model) {
1342 return value ? "_fractional".loc() : "";
1344 formatPrice: function (value, view, model) {
1345 var sold = model.get("isSold");
1346 if (XT.session.privileges.get("ViewListPrices") && sold) {
1347 var scale = XT.locale.salesPriceScale;
1348 return Globalize.format(value, "c" + scale);
1350 view.addRemoveClass("placeholder", true);
1352 return "_notSold".loc();
1356 formatPriceUnit: function (value, view, model) {
1357 if (XT.session.privileges.get("ViewListPrices") && model.get("isSold")) {
1362 formatDescription: function (value, view, model) {
1363 var descrip1 = model.get("description1") || "",
1364 descrip2 = model.get("description2") || "",
1365 sep = descrip2 ? " - " : "";
1366 return descrip1 + sep + descrip2;
1370 XV.registerModelList("XM.ItemRelation", "XV.ItemList");
1372 // ..........................................................
1377 name: "XV.ItemGroupList",
1379 label: "_itemGroups".loc(),
1380 collection: "XM.ItemGroupRelationCollection",
1385 {kind: "XV.ListItem", components: [
1386 {kind: "FittableColumns", components: [
1387 {kind: "XV.ListColumn", classes: "short",
1389 {kind: "XV.ListAttr", attr: "name", isKey: true}
1391 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1392 {kind: "XV.ListAttr", attr: "description"}
1399 // ..........................................................
1404 name: "XV.ItemSiteList",
1406 label: "_itemSites".loc(),
1407 collection: "XM.ItemSiteListItemCollection",
1409 {attribute: 'item.number'}
1411 parameterWidget: "XV.ItemSiteListParameters",
1413 {kind: "XV.ListItem", components: [
1414 {kind: "FittableColumns", components: [
1415 {kind: "XV.ListColumn", classes: "first", components: [
1416 {kind: "FittableColumns", components: [
1417 {kind: "XV.ListAttr", attr: "item.number", isKey: true},
1418 {kind: "XV.ListAttr", attr: "item.barcode", fit: true, classes: "right"}
1420 {kind: "FittableColumns", components: [
1421 {kind: "XV.ListAttr", attr: "item.description1"},
1422 {kind: "XV.ListAttr", attr: "item.aliases", fit: true,
1423 formatter: "formatAliases", classes: "right"}
1426 {kind: "XV.ListColumn", classes: "second",
1428 {kind: "XV.ListAttr", attr: "site.code", classes: "bold"},
1429 {kind: "XV.ListAttr", attr: "site.description"}
1434 formatActive: function (value, view, model) {
1435 return value ? "_active".loc() : "";
1437 formatAliases: function (value, view, model) {
1438 return value.map(function (model) {
1439 return model.get("aliasNumber");
1442 formatSold: function (value, view, model) {
1443 return value ? "_sold".loc() : "";
1447 XV.registerModelList("XM.ItemSiteRelation", "XV.ItemSiteList");
1449 // ..........................................................
1454 name: "XV.LedgerAccountList",
1456 label: "_ledgerAccounts".loc(),
1457 collection: "XM.LedgerAccountRelationCollection",
1461 parameterWidget: "XV.LedgerAccountListParameters",
1463 {kind: "XV.ListItem", components: [
1464 {kind: "FittableColumns", components: [
1465 {kind: "XV.ListColumn", classes: "first", components: [
1466 {kind: "FittableColumns", components: [
1467 {kind: "XV.ListAttr", attr: "name", isKey: true},
1468 {kind: "XV.ListAttr", attr: "getAccountTypeString", fit: true,
1471 {kind: "XV.ListAttr", attr: "description"}
1473 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1474 {kind: "XV.ListAttr", attr: "externalReference"},
1475 {kind: "XV.ListAttr", attr: "isActive", formatter: "formatActive"}
1480 formatActive: function (value, view, model) {
1481 return value ? "" : "_inactive".loc();
1485 // ..........................................................
1490 name: "XV.OpportunityList",
1492 collection: "XM.OpportunityListItemCollection",
1494 {attribute: 'priorityOrder'},
1495 {attribute: 'targetClose'},
1496 {attribute: 'name'},
1497 {attribute: 'number', numeric: true}
1499 label: "_opportunities".loc(),
1500 parameterWidget: "XV.OpportunityListParameters",
1502 {kind: "XV.ListItem", components: [
1503 {kind: "FittableColumns", components: [
1504 {kind: "XV.ListColumn", classes: "first", components: [
1505 {kind: "FittableColumns", components: [
1506 {kind: "XV.ListAttr", attr: "number", isKey: true},
1507 {kind: "XV.ListAttr", attr: "targetClose", fit: true,
1508 placeholder: "_noCloseTarget".loc(),
1511 {kind: "FittableColumns", components: [
1512 {kind: "XV.ListAttr", attr: "name"},
1513 {kind: "XV.ListAttr", attr: "amount", classes: "right",
1514 formatter: "formatAmount"}
1517 {kind: "XV.ListColumn", classes: "second",
1519 {kind: "XV.ListAttr", attr: "account.name",
1520 placeholder: "_noAccountName".loc()},
1521 {kind: "XV.ListAttr", attr: "contact.name"}
1523 {kind: "XV.ListColumn", classes: "third",
1525 {kind: "XV.ListAttr", attr: "opportunityStage.name",
1526 placeholder: "_noStage".loc()},
1527 {kind: "XV.ListAttr", attr: "assignedTo.username"}
1529 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1530 {kind: "XV.ListAttr", attr: "priority.name",
1531 placeholder: "_noPriority".loc()},
1532 {kind: "XV.ListAttr", attr: "opportunityType.name",
1533 placeholder: "_noType".loc()}
1538 formatAmount: function (value, view, model) {
1539 var currency = model ? model.get("currency") : false,
1540 scale = XT.locale.moneyScale;
1541 return currency ? currency.format(value, scale) : "";
1545 XV.registerModelList("XM.OpportunityListItem", "XV.OpportunityList");
1546 XV.registerModelList("XM.OpportunityRelation", "XV.OpportunityList");
1548 // ..........................................................
1553 name: "XV.PlannerCodeList",
1555 label: "_plannerCodes".loc(),
1556 collection: "XM.PlannerCodeCollection",
1560 parameterWidget: "XV.PlannerCodeListParameters",
1562 {kind: "XV.ListItem", components: [
1563 {kind: "FittableColumns", components: [
1564 {kind: "XV.ListColumn", classes: "first", components: [
1565 {kind: "FittableColumns", components: [
1566 {kind: "XV.ListAttr", attr: "code", isKey: true},
1567 {kind: "XV.ListAttr", attr: "name", fit: true, classes: "right"}
1575 XV.registerModelList("XM.PlannerCode", "XV.PlannerCodeList");
1577 // ..........................................................
1582 name: "XV.ProductCategoryList",
1584 label: "_productCategories".loc(),
1585 collection: "XM.ProductCategoryCollection",
1590 {kind: "XV.ListItem", components: [
1591 {kind: "FittableColumns", components: [
1592 {kind: "XV.ListColumn", classes: "short",
1594 {kind: "XV.ListAttr", attr: "code", isKey: true}
1596 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1597 {kind: "XV.ListAttr", attr: "description"}
1604 // ..........................................................
1609 name: "XV.ProjectList",
1611 label: "_projects".loc(),
1612 collection: "XM.ProjectListItemCollection",
1614 {attribute: "number" }
1616 parameterWidget: "XV.ProjectListParameters",
1618 {kind: "FittableColumns", classes: "xv-list-header",
1620 {kind: "XV.ListColumn", classes: "name-column", components: [
1621 {content: "_name".loc()},
1622 {content: "_description".loc()},
1623 {content: "_account".loc()}
1625 {kind: "XV.ListColumn", classes: "right-column", components: [
1626 {content: "_dueDate".loc()},
1627 {content: "_priority".loc()},
1628 {content: "_complete".loc()}
1630 {kind: "XV.ListColumn", classes: "short", components: [
1631 {content: "_status".loc()},
1632 {content: "_assignedTo".loc()},
1633 {content: "_type".loc()}
1635 {kind: "XV.ListColumn", classes: "right-column"},
1636 {kind: "XV.ListColumn", classes: "right-column", components: [
1637 {content: "_budgeted".loc()},
1638 {content: "_actual".loc()},
1639 {content: "_balance".loc()}
1644 {kind: "XV.ListItem", components: [
1645 {kind: "FittableColumns", components: [
1646 {kind: "XV.ListColumn", classes: "name-column", components: [
1647 {kind: "XV.ListAttr", attr: "number", isKey: true},
1648 {kind: "XV.ListAttr", attr: "name"},
1649 {kind: "XV.ListAttr", attr: "account.name"}
1651 {kind: "XV.ListColumn", classes: "right-column", components: [
1652 {kind: "XV.ListAttr", attr: "dueDate"},
1653 {kind: "XV.ListAttr", attr: "priority.name",
1654 placeholder: "_noPriority".loc()},
1655 {kind: "XV.ListAttr", attr: "percentComplete"}
1657 {kind: "XV.ListColumn", classes: "short",
1659 {kind: "XV.ListAttr", attr: "getProjectStatusString"},
1660 {kind: "XV.ListAttr", attr: "assignedTo.username",
1661 placeholder: "_noAssignedTo".loc()},
1662 {kind: "XV.ListAttr", attr: "projectType.code",
1663 placeholder: "_noProjectType".loc()},
1665 {kind: "XV.ListColumn", classes: "right-column", components: [
1666 {kind: "XV.ListAttr", attr: "budgetedExpenses",
1667 classes: "text-align-right", formatter: "formatExpenses"},
1668 {kind: "XV.ListAttr", attr: "actualExpenses",
1669 classes: "text-align-right", formatter: "formatExpenses"},
1670 {kind: "XV.ListAttr", attr: "balanceExpenses",
1671 classes: "text-align-right", formatter: "formatExpenses"}
1673 {kind: "XV.ListColumn", classes: "right-column", fit: true,
1675 {kind: "XV.ListAttr", attr: "budgetedHours",
1676 classes: "text-align-right", formatter: "formatHours"},
1677 {kind: "XV.ListAttr", attr: "actualHours",
1678 classes: "text-align-right", formatter: "formatHours"},
1679 {kind: "XV.ListAttr", attr: "balanceHours",
1680 classes: "text-align-right", formatter: "formatHours"}
1685 formatHours: function (value, view, model) {
1686 view.addRemoveClass("error", value < 0);
1687 var scale = XT.locale.quantityScale;
1688 return Globalize.format(value, "n" + scale) + " " + "_hrs".loc();
1690 formatExpenses: function (value, view, model) {
1691 view.addRemoveClass("error", value < 0);
1692 var scale = XT.locale.currencyScale;
1693 return Globalize.format(value, "c" + scale);
1698 XV.registerModelList("XM.ProjectListItem", "XV.ProjectList");
1699 XV.registerModelList("XM.ProjectRelation", "XV.ProjectList");
1701 // ..........................................................
1706 name: "XV.ProspectList",
1708 label: "_prospects".loc(),
1709 collection: "XM.ProspectRelationCollection",
1715 method: "convertProspect",
1716 privilege: "MaintainCustomerMasters",
1720 {attribute: 'number'}
1722 parameterWidget: "XV.ProspectListParameters",
1724 {kind: "XV.ListItem", components: [
1725 {kind: "FittableColumns", components: [
1726 {kind: "XV.ListColumn", classes: "first", components: [
1727 {kind: "FittableColumns", components: [
1728 {kind: "XV.ListAttr", attr: "number", isKey: true},
1729 {kind: "XV.ListAttr", attr: "contact.phone", fit: true,
1732 {kind: "FittableColumns", components: [
1733 {kind: "XV.ListAttr", attr: "name"},
1734 {kind: "XV.ListAttr", attr: "contact.primaryEmail", classes: "right"}
1737 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1738 {kind: "XV.ListAttr", attr: "contact.name",
1739 placeholder: "_noContact".loc()},
1740 {kind: "XV.ListAttr", attr: "contact.address"}
1746 Convert the prospect from the list into a customer model. The way we
1747 do this is to open a customer workspace and then call the model method
1748 convertFromProspect AFTER the workspace is initialized. That way
1749 the view and the model get bound together correctly. The user will have
1750 to fill out some customer-specific fields, and when they save a new
1751 customer will be created.
1753 convertProspect: function (inEvent) {
1754 var model = inEvent.model,
1756 success = function () {
1757 this.getValue().convertFromProspect(modelId);
1761 workspace: "XV.CustomerWorkspace",
1763 name: model.get("name"),
1764 number: model.get("number")
1772 XV.registerModelList("XM.ProspectRelation", "XV.ProspectList");
1774 // ..........................................................
1775 // SALES EMAIL PROFILE
1779 name: "XV.SalesEmailProfileList",
1780 kind: "XV.EmailProfileList",
1781 label: "_salesEmailProfiles".loc(),
1782 collection: "XM.SalesEmailProfileCollection"
1785 // ..........................................................
1790 name: "XV.SalesOrderList",
1792 label: "_salesOrders".loc(),
1793 collection: "XM.SalesOrderListItemCollection",
1794 parameterWidget: "XV.SalesOrderListParameters",
1796 {name: "print", privilege: "ViewSalesOrders", method: "doPrint", isViewMethod: true},
1797 {name: "email", privilege: "ViewSalesOrders", method: "doEmail", isViewMethod: true}
1800 {attribute: 'number'}
1803 {kind: "XV.ListItem", components: [
1804 {kind: "FittableColumns", components: [
1805 {kind: "FittableColumns", components: [
1806 {kind: "XV.ListColumn", classes: "name-column", components: [
1807 {kind: "XV.ListAttr", attr: "number", isKey: true},
1808 {kind: "XV.ListAttr", attr: "customer.name"}
1810 {kind: "XV.ListColumn", components: [
1811 {kind: "XV.ListAttr", attr: "formatStatus"}
1813 {kind: "XV.ListColumn", classes: "right-column", components: [
1814 {kind: "XV.ListAttr", attr: "scheduleDate",
1815 placeholder: "_noSchedule".loc()},
1816 {kind: "XV.ListAttr", attr: "total", formatter: "formatTotal"}
1818 {kind: "XV.ListColumn", fit: true, components: [
1819 {kind: "XV.ListAttr", formatter: "formatName"},
1820 {kind: "XV.ListAttr", formatter: "formatShiptoOrBillto"}
1826 formatBillto: function (value, view, model) {
1827 var city = model.get("billtoCity"),
1828 state = model.get("billtoState"),
1829 country = model.get("billtoCountry");
1830 return XM.Address.formatShort(city, state, country);
1833 Returns Shipto Name if one exists, otherwise Billto Name.
1835 formatName: function (value, view, model) {
1836 return model.get("shiptoName") || model.get("billtoName");
1838 formatTotal: function (value, view, model) {
1839 var currency = model ? model.get("currency") : false,
1840 scale = XT.locale.moneyScale;
1841 return currency ? currency.format(value, scale) : "";
1844 formatShipto: function (value, view, model) {
1845 var city = model.get("shiptoCity"),
1846 state = model.get("shiptoState"),
1847 country = model.get("shiptoCountry");
1848 return XM.Address.formatShort(city, state, country);
1851 Returns formatted Shipto City, State and Country if
1852 Shipto Name exists, otherwise Billto location.
1854 formatShiptoOrBillto: function (value, view, model) {
1855 var hasShipto = model.get("shiptoName") ? true : false,
1856 cityAttr = hasShipto ? "shiptoCity": "billtoCity",
1857 stateAttr = hasShipto ? "shiptoState" : "billtoState",
1858 countryAttr = hasShipto ? "shiptoCountry" : "billtoCountry",
1859 city = model.get(cityAttr),
1860 state = model.get(stateAttr),
1861 country = model.get(countryAttr);
1862 return XM.Address.formatShort(city, state, country);
1866 XV.registerModelList("XM.SalesOrderRelation", "XV.SalesOrderList");
1868 // ..........................................................
1873 name: "XV.QuoteList",
1874 kind: "XV.SalesOrderList",
1876 {attribute: 'number'}
1883 method: "convertQuote",
1884 privilege: "ConvertQuotes",
1888 label: "_quotes".loc(),
1889 collection: "XM.QuoteListItemCollection",
1890 parameterWidget: "XV.QuoteListParameters",
1891 formatDate: function (value, view, model) {
1892 var isLate = model && model.get('expireDate') &&
1893 (XT.date.compareDate(value, new Date()) < 1);
1894 view.addRemoveClass("error", isLate);
1897 convertQuote: function (inEvent) {
1898 var model = inEvent.model,
1900 customer = model.get("customer"),
1901 K = XM.CustomerProspectRelation,
1904 // In case we are converting a prospect
1905 convertToCustomer = function (resp) {
1906 if (!resp.answer) { return; }
1909 workspace: "XV.CustomerWorkspace",
1911 number: customer.get("number"),
1912 name: customer.get("name")
1914 success: afterCustomerCreated,
1915 callback: convertToSalesOrder,
1920 afterCustomerCreated = function () {
1921 this.getValue().convertFromProspect(customer.id);
1924 convertToSalesOrder = function () {
1925 XM.SalesOrder.convertFromQuote(model.id, {
1926 success: afterQuoteConvertedSuccess
1930 afterQuoteConvertedSuccess = function (resp) {
1933 workspace: "XV.SalesOrderWorkspace",
1934 success: afterSalesOrderCreated,
1939 afterSalesOrderCreated = function () {
1940 var value = this.getValue(),
1941 gridBox = this.$.salesOrderLineItemBox;
1943 value.setStatus(XM.Model.BUSY_FETCHING);
1945 value.revertStatus();
1947 //Hack to force grid to refresh. Why doesn't it on its own?
1948 gridBox.valueChanged();
1949 gridBox.setDisabled(false);
1953 // Get the process started one way or another
1954 if (customer.get("status") === K.PROSPECT_STATUS) {
1956 type: XM.Model.QUESTION,
1957 callback: convertToCustomer,
1958 message: "_convertProspect".loc()
1961 convertToSalesOrder();
1966 XV.registerModelList("XM.QuoteRelation", "XV.QuoteList");
1968 // ..........................................................
1973 name: "XV.ReasonCodeList",
1975 label: "_reasonCodes".loc(),
1976 collection: "XM.ReasonCodeCollection",
1981 {kind: "XV.ListItem", components: [
1982 {kind: "FittableColumns", components: [
1983 {kind: "XV.ListColumn", classes: "first",
1985 {kind: "XV.ListAttr", attr: "code", isKey: true}
1987 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
1988 {kind: "XV.ListAttr", attr: "description"}
1995 // ..........................................................
2000 name: "XV.ReturnList",
2001 kind: "XV.InvoiceList",
2002 label: "_returns".loc(),
2004 parameterWidget: "XV.ReturnListParameters",
2005 collection: "XM.ReturnListItemCollection",
2007 {name: "void", privilege: "VoidPostedARCreditMemos",
2008 prerequisite: "canVoid", method: "doVoid" },
2009 {name: "post", privilege: "PostARDocuments",
2010 prerequisite: "canPost", method: "doPost" },
2011 {name: "print", privilege: "PrintCreditMemos",
2014 create: function () {
2015 this.inherited(arguments);
2016 this.$.dateField.setAttr("returnDate");
2019 XV.registerModelList("XM.ReturnRelation", "XV.ReturnList");
2021 // ..........................................................
2026 name: "XV.SaleTypeList",
2028 label: "_saleTypes".loc(),
2029 collection: "XM.SaleTypeCollection",
2030 parameterWidget: "XV.SaleTypeListParameters",
2035 {kind: "XV.ListItem", components: [
2036 {kind: "FittableColumns", components: [
2037 {kind: "XV.ListColumn", classes: "short",
2039 {kind: "XV.ListAttr", attr: "code", isKey: true}
2041 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2042 {kind: "XV.ListAttr", attr: "description"}
2049 XV.registerModelList("XM.SaleTypeRelation", "XV.SaleTypeList");
2051 // ..........................................................
2056 name: "XV.SalesRepList",
2058 label: "_salesRep".loc(),
2059 collection: "XM.SalesRepCollection",
2060 parameterWidget: "XV.SalesRepListParameters",
2062 {attribute: 'number'}
2065 {kind: "XV.ListItem", components: [
2066 {kind: "FittableColumns", components: [
2067 {kind: "XV.ListColumn", classes: "short",
2069 {kind: "XV.ListAttr", attr: "number", isKey: true}
2071 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2072 {kind: "XV.ListAttr", attr: "name"}
2079 XV.registerModelList("XM.SalesRepRelation", "XV.SalesRepList");
2081 // ..........................................................
2086 name: "XV.SiteList",
2088 label: "_sites".loc(),
2089 collection: "XM.SiteListItemCollection",
2093 parameterWidget: "XV.SiteListParameters",
2095 {kind: "XV.ListItem", components: [
2096 {kind: "FittableColumns", components: [
2097 {kind: "XV.ListColumn", classes: "first", components: [
2098 {kind: "FittableColumns", components: [
2099 {kind: "XV.ListAttr", attr: "code", isKey: true},
2100 {kind: "XV.ListAttr", attr: "description", fit: true, classes: "right"}
2102 {kind: "XV.ListAttr", attr: "siteType.description"}
2109 XV.registerModelList("XM.SiteRelation", "XV.SiteList");
2111 // ..........................................................
2116 name: "XV.ShiftList",
2118 label: "_shifts".loc(),
2119 collection: "XM.ShiftCollection",
2120 parameterWidget: "XV.ShiftListParameters",
2122 {attribute: 'number'}
2125 {kind: "XV.ListItem", components: [
2126 {kind: "FittableColumns", components: [
2127 {kind: "XV.ListColumn", classes: "short",
2129 {kind: "XV.ListAttr", attr: "number", isKey: true}
2131 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2132 {kind: "XV.ListAttr", attr: "name"}
2139 // ..........................................................
2144 name: "XV.ShipViaList",
2146 label: "_shipVias".loc(),
2147 collection: "XM.ShipViaCollection",
2152 {kind: "XV.ListItem", components: [
2153 {kind: "FittableColumns", components: [
2154 {kind: "XV.ListColumn", classes: "short",
2156 {kind: "XV.ListAttr", attr: "code", isKey: true}
2158 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2159 {kind: "XV.ListAttr", attr: "description"}
2165 XV.registerModelList("XM.ShipVia", "XV.ShipViaList");
2167 // ..........................................................
2172 name: "XV.ShipZoneList",
2174 label: "_shipZones".loc(),
2175 collection: "XM.ShipZoneCollection",
2176 parameterWidget: "XV.ShipZoneListParameters",
2181 {kind: "XV.ListItem", components: [
2182 {kind: "FittableColumns", components: [
2183 {kind: "XV.ListColumn", classes: "short",
2185 {kind: "XV.ListAttr", attr: "name", isKey: true}
2187 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2188 {kind: "XV.ListAttr", attr: "description"}
2195 XV.registerModelList("XM.ShipZoneRelation", "XV.ShipZoneList");
2197 // ..........................................................
2202 name: "XV.TaxAssignmentList",
2204 label: "_taxAssignment".loc(),
2205 collection: "XM.TaxAssignmentCollection",
2206 parameterWidget: "XV.TaxAssignmentListParameters",
2211 {kind: "XV.ListItem", components: [
2212 {kind: "FittableColumns", components: [
2213 {kind: "XV.ListColumn", classes: "short", components: [
2214 {kind: "XV.ListAttr", attr: "tax.code", isKey: true}
2216 {kind: "XV.ListColumn", classes: "short", components: [
2217 {kind: "XV.ListAttr", attr: "taxType.name"}
2224 // ..........................................................
2229 name: "XV.TaxAuthorityList",
2231 label: "_taxAuthority".loc(),
2232 collection: "XM.TaxAuthorityCollection",
2233 parameterWidget: "XV.TaxAuthorityListParameters",
2238 {kind: "XV.ListItem", components: [
2239 {kind: "FittableColumns", components: [
2240 {kind: "XV.ListColumn", classes: "short",
2242 {kind: "XV.ListAttr", attr: "code", isKey: true}
2244 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2245 {kind: "XV.ListAttr", attr: "name"}
2252 // ..........................................................
2257 name: "XV.TaxCodeList",
2259 label: "_taxCode".loc(),
2260 collection: "XM.TaxCodeCollection",
2261 parameterWidget: "XV.TaxCodeListParameters",
2266 {kind: "XV.ListItem", components: [
2267 {kind: "FittableColumns", components: [
2268 {kind: "XV.ListColumn", classes: "short",
2270 {kind: "XV.ListAttr", attr: "code", isKey: true}
2272 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2273 {kind: "XV.ListAttr", attr: "description"}
2280 XV.registerModelList("XM.TaxCodeRelation", "XV.TaxCodeList");
2282 // ..........................................................
2287 name: "XV.TaxClassList",
2289 label: "_taxClass".loc(),
2290 collection: "XM.TaxClassCollection",
2291 parameterWidget: "XV.TaxClassListParameters",
2296 {kind: "XV.ListItem", components: [
2297 {kind: "FittableColumns", components: [
2298 {kind: "XV.ListColumn", classes: "short",
2300 {kind: "XV.ListAttr", attr: "code", isKey: true}
2302 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2303 {kind: "XV.ListAttr", attr: "description"}
2310 XV.registerModelList("XM.TaxClassRelation", "XV.TaxClassList");
2312 // ..........................................................
2317 name: "XV.TaxRateList",
2319 label: "_taxRate".loc(),
2320 collection: "XM.TaxRateCollection",
2321 parameterWidget: "XV.TaxRateListParameters",
2326 {kind: "XV.ListItem", components: [
2327 {kind: "FittableColumns", components: [
2328 {kind: "XV.ListColumn", classes: "short", components: [
2329 {kind: "XV.ListAttr", attr: "tax.code", isKey: true}
2331 {kind: "XV.ListColumn", classes: "short", components: [
2332 {kind: "XV.ListAttr", attr: "percent"}
2339 // ..........................................................
2344 name: "XV.TaxTypeList",
2346 label: "_taxType".loc(),
2347 collection: "XM.TaxTypeCollection",
2348 parameterWidget: "XV.TaxTypeListParameters",
2353 {kind: "XV.ListItem", components: [
2354 {kind: "FittableColumns", components: [
2355 {kind: "XV.ListColumn", classes: "short",
2357 {kind: "XV.ListAttr", attr: "name", isKey: true}
2359 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2360 {kind: "XV.ListAttr", attr: "description"}
2367 XV.registerModelList("XM.TaxTypeRelation", "XV.TaxTypeList");
2369 // ..........................................................
2374 name: "XV.TaxZoneList",
2376 label: "_taxZone".loc(),
2377 collection: "XM.TaxZoneCollection",
2378 parameterWidget: "XV.TaxZoneListParameters",
2383 {kind: "XV.ListItem", components: [
2384 {kind: "FittableColumns", components: [
2385 {kind: "XV.ListColumn", classes: "short",
2387 {kind: "XV.ListAttr", attr: "code", isKey: true}
2389 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2390 {kind: "XV.ListAttr", attr: "description"}
2397 XV.registerModelList("XM.TaxZoneRelation", "XV.TaxZoneList");
2399 // ..........................................................
2404 name: "XV.TermsList",
2406 label: "_terms".loc(),
2407 collection: "XM.TermsCollection",
2408 parameterWidget: "XV.TermsListParameters",
2413 {kind: "XV.ListItem", components: [
2414 {kind: "FittableColumns", components: [
2415 {kind: "XV.ListColumn", classes: "short",
2417 {kind: "XV.ListAttr", attr: "code", isKey: true}
2419 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2420 {kind: "XV.ListAttr", attr: "description"}
2427 XV.registerModelList("XM.TermsRelation", "XV.TermsList");
2429 // ..........................................................
2434 name: "XV.ToDoList",
2436 label: "_toDo".loc(),
2437 collection: "XM.ToDoListItemCollection",
2438 parameterWidget: "XV.ToDoListParameters",
2440 {attribute: 'priorityOrder'},
2441 {attribute: 'dueDate'},
2445 {kind: "XV.ListItem", components: [
2446 {kind: "FittableColumns", components: [
2447 {kind: "XV.ListColumn", classes: "first", components: [
2448 {kind: "FittableColumns", components: [
2449 {kind: "XV.ListAttr", attr: "name", isKey: true},
2450 {kind: "XV.ListAttr", attr: "dueDate", fit: true,
2451 placeholder: "_noDueDate".loc(), classes: "right"}
2453 {kind: "XV.ListAttr", attr: "description",
2454 placeholder: "_noDescription".loc()}
2456 {kind: "XV.ListColumn", classes: "second",
2458 {kind: "XV.ListAttr", attr: "account.name",
2459 placeholder: "_noAccountName".loc()},
2460 {kind: "XV.ListAttr", attr: "contact.name"}
2462 {kind: "XV.ListColumn", classes: "third",
2464 {kind: "XV.ListAttr", attr: "getToDoStatusString"},
2465 {kind: "XV.ListAttr", attr: "owner.username"}
2467 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2468 {kind: "XV.ListAttr", attr: "priority.name",
2469 placeholder: "_noPriority".loc()}
2476 XV.registerModelList("XM.ToDoRelation", "XV.ToDoList");
2478 // ..........................................................
2485 label: "_urls".loc(),
2486 collection: "XM.UrlCollection",
2487 parameterWidget: "XV.UrlListParameters",
2492 {kind: "XV.ListItem", components: [
2493 {kind: "FittableColumns", components: [
2494 {kind: "XV.ListColumn", classes: "short",
2496 {kind: "XV.ListAttr", attr: "name", isKey: true}
2498 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2499 {kind: "XV.ListAttr", attr: "path"}
2506 XV.registerModelList("XM.Url", "XV.UrlList");
2508 // ..........................................................
2513 name: "XV.UserAccountList",
2515 label: "_userAccounts".loc(),
2516 collection: "XM.UserAccountRelationCollection",
2517 parameterWidget: "XV.UserAccountListParameters",
2519 {attribute: 'username'}
2522 {kind: "XV.ListItem", components: [
2523 {kind: "FittableColumns", components: [
2524 {kind: "XV.ListColumn", classes: "short", components: [
2525 {kind: "XV.ListAttr", attr: "username", isKey: true}
2527 {kind: "XV.ListColumn", classes: "short", components: [
2528 {kind: "XV.ListAttr", attr: "propername"}
2535 XV.registerModelList("XM.UserAccountRelation", "XV.UserAccountList");
2537 // ..........................................................
2538 // STATES AND COUNTRIES
2542 name: "XV.AbbreviationList",
2545 {kind: "XV.ListItem", components: [
2546 {kind: "FittableColumns", components: [
2547 {kind: "XV.ListColumn", classes: "short",
2549 {kind: "XV.ListAttr", attr: "abbreviation", isKey: true}
2551 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2552 {kind: "XV.ListAttr", attr: "name"}
2560 name: "XV.StateList",
2561 kind: "XV.AbbreviationList",
2562 label: "_states".loc(),
2563 collection: "XM.StateCollection",
2564 query: {orderBy: [{ attribute: 'abbreviation' }] }
2568 name: "XV.CountryList",
2569 kind: "XV.AbbreviationList",
2570 label: "_countries".loc(),
2571 collection: "XM.CountryCollection",
2573 {attribute: 'abbreviation'}
2577 // ..........................................................
2582 name: "XV.VendorList",
2584 label: "_vendors".loc(),
2585 collection: "XM.VendorListItemCollection",
2587 {attribute: 'number'}
2589 parameterWidget: "XV.VendorListParameters",
2591 {kind: "XV.ListItem", components: [
2592 {kind: "FittableColumns", components: [
2593 {kind: "XV.ListColumn", classes: "first", components: [
2594 {kind: "FittableColumns", components: [
2595 {kind: "XV.ListAttr", attr: "number", isKey: true},
2596 {kind: "XV.ListAttr", attr: "primaryContact.phone", fit: true,
2599 {kind: "FittableColumns", components: [
2600 {kind: "XV.ListAttr", attr: "name"},
2601 {kind: "XV.ListAttr", attr: "primaryContact.primaryEmail", classes: "right"}
2604 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2605 {kind: "XV.ListAttr", attr: "primaryContact.name",
2606 placeholder: "_noContact".loc()},
2607 {kind: "XV.ListAttr", attr: "address"}
2614 XV.registerModelList("XM.VendorRelation", "XV.VendorList");
2616 // ..........................................................
2621 name: "XV.VendorAddressList",
2623 collection: "XM.VendorAddressRelationCollection",
2624 parameterWidget: "XV.VendorAddressParameters",
2629 {kind: "XV.ListItem", components: [
2630 {kind: "FittableColumns", components: [
2631 {kind: "XV.ListColumn", classes: "short",
2633 {kind: "XV.ListAttr", attr: "code", isKey: true}
2635 {kind: "XV.ListColumn", fit: true, components: [
2636 {kind: "XV.ListAttr", attr: "name"},
2637 {kind: "XV.ListAttr", formatter: "formatAddress",
2638 classes: "xv-addresslist-attr", allowHtml: true}
2643 formatAddress: function (value, view, model) {
2644 var address = model.get("address");
2645 return address.format(true);
2649 XV.registerModelList("XM.VendarAddressRelation", "XV.VendorAddressList");
2652 name: "XV.NameList",
2658 {kind: "XV.ListItem", components: [
2659 {kind: "FittableColumns", components: [
2660 {kind: "XV.ListColumn", classes: "first",
2662 {kind: "XV.ListAttr", attr: "name", isKey: true}
2668 All of these lists follow a very similar naming convention.
2669 Apply that convention unless the list overrides the label
2670 or collection attribute.
2672 create: function () {
2673 var kindName = this.kind.substring(0, this.kind.length - 4).substring(3);
2674 if (!this.getLabel()) {
2675 this.setLabel(this.determineLabel(kindName));
2677 if (!this.getCollection()) {
2678 this.setCollection("XM." + kindName + "Collection");
2680 this.inherited(arguments);
2683 determineLabel: function (kindName) {
2684 return ("_" + kindName.camelize().pluralize()).loc();
2688 // ..........................................................
2689 // INCIDENT CATEGORIES, RESOLUTIONS, SEVERITIES,
2691 // OPPORTUNITY SOURCES, STAGES, TYPES,
2693 // Basically anything whose rows are name and description
2696 name: "XV.NameDescriptionList",
2697 kind: "XV.NameList",
2699 {kind: "XV.ListItem", components: [
2700 {kind: "FittableColumns", components: [
2701 {kind: "XV.ListColumn", classes: "short",
2703 {kind: "XV.ListAttr", attr: "name", isKey: true}
2705 {kind: "XV.ListColumn", classes: "last", fit: true, components: [
2706 {kind: "XV.ListAttr", attr: "description"}
2714 name: "XV.IncidentCategoryList",
2715 kind: "XV.NameDescriptionList"
2719 name: "XV.IncidentResolutionList",
2720 kind: "XV.NameDescriptionList"
2724 name: "XV.IncidentSeverityList",
2725 kind: "XV.NameDescriptionList"
2729 name: "XV.PriorityList",
2730 kind: "XV.NameDescriptionList"
2734 name: "XV.UnitList",
2735 kind: "XV.NameDescriptionList"
2739 name: "XV.OpportunitySourceList",
2740 kind: "XV.NameDescriptionList",
2742 query: {orderBy: [{ attribute: 'name' }] }
2747 name: "XV.OpportunityStageList",
2748 kind: "XV.NameDescriptionList",
2750 query: {orderBy: [{ attribute: 'name' }] }
2755 name: "XV.OpportunityTypeList",
2756 kind: "XV.NameDescriptionList",
2758 query: {orderBy: [{ attribute: 'name' }] }
2763 name: "XV.SiteTypeList",
2764 kind: "XV.NameDescriptionList",
2765 collection: "XM.SiteTypeCollection"
2769 name: "XV.UserAccountRoleList",
2770 kind: "XV.NameDescriptionList",
2771 collection: "XM.UserAccountRoleListItemCollection"
2775 name: "XV.CharacteristicList",
2776 kind: "XV.NameList",
2777 collection: "XM.CharacteristicCollection"