1 (function (angular
, $, _
) {
3 function OptionGroup(values
) {
4 this.get = function get(value
) {
5 var r
= _
.where(values
, {value
: '' + value
});
6 return r
.length
> 0 ? r
[0] : null;
8 this.getByName
= function get(name
) {
9 var r
= _
.where(values
, {name
: '' + name
});
10 return r
.length
> 0 ? r
[0] : null;
12 this.getAll
= function getAll() {
17 angular
.module('crmMailingAB').factory('crmMailingABCriteria', function () {
18 // TODO Get data from server
20 '1': {value
: 'subject', name
: 'subject', label
: ts('Test different "Subject" lines')},
21 '2': {value
: 'from', name
: 'from', label
: ts('Test different "From" lines')},
22 '3': {value
: 'full_email', name
: 'full_email', label
: ts('Test entirely different emails')}
24 return new OptionGroup(values
);
27 angular
.module('crmMailingAB').factory('crmMailingABStatus', function () {
28 // TODO Get data from server
30 '1': {value
: '1', name
: 'Draft', label
: ts('Draft')},
31 '2': {value
: '2', name
: 'Testing', label
: ts('Testing')},
32 '3': {value
: '3', name
: 'Final', label
: ts('Final')}
34 return new OptionGroup(values
);
37 // CrmMailingAB is a data-model which combines an AB test (APIv3 "MailingAB"), three mailings (APIv3 "Mailing"),
38 // and three sets of attachments (APIv3 "Attachment").
41 // var abtest = new CrmMailingAB(123);
42 // abtest.load().then(function(){
43 // alert("Mailing A is named "+abtest.mailings.a.name);
45 angular
.module('crmMailingAB').factory('CrmMailingAB', function (crmApi
, crmMailingMgr
, $q
, CrmAttachments
) {
46 function CrmMailingAB(id
) {
49 this.attachments
= {};
52 angular
.extend(CrmMailingAB
.prototype, {
53 getAutosaveSignature: function() {
54 //modified date is unset so that it gets ignored in comparison
55 //its value is overwritten with the save response from the server and may differ from the local value,
56 //which would result in an unnecessary auto-save
57 var mailings
= angular
.copy(this.mailings
);
58 _
.each(mailings
, function(mailing
) {
59 mailing
.modified_date
= undefined;
64 this.attachments
.a
.getAutosaveSignature(),
65 this.attachments
.b
.getAutosaveSignature(),
66 this.attachments
.c
.getAutosaveSignature()
69 // @return Promise CrmMailingAB
70 load
: function load() {
71 var crmMailingAB
= this;
72 if (!crmMailingAB
.id
) {
79 testing_criteria
: 'subject',
80 winner_criteria
: null,
82 declare_winning_time
: null,
85 var mailingDefaults
= {
86 // Most defaults provided by Mailing.create API, but we
87 // want to force-enable tracking.
90 mailing_type
:"experiment"
92 crmMailingAB
.mailings
.a
= crmMailingMgr
.create(mailingDefaults
);
93 crmMailingAB
.mailings
.b
= crmMailingMgr
.create(mailingDefaults
);
94 mailingDefaults
.mailing_type
= 'winner';
95 crmMailingAB
.mailings
.c
= crmMailingMgr
.create(mailingDefaults
);
96 crmMailingAB
.attachments
.a
= new CrmAttachments(function () {
97 return {entity_table
: 'civicrm_mailing', entity_id
: crmMailingAB
.ab
.mailing_id_a
};
99 crmMailingAB
.attachments
.b
= new CrmAttachments(function () {
100 return {entity_table
: 'civicrm_mailing', entity_id
: crmMailingAB
.ab
.mailing_id_b
};
102 crmMailingAB
.attachments
.c
= new CrmAttachments(function () {
103 return {entity_table
: 'civicrm_mailing', entity_id
: crmMailingAB
.ab
.mailing_id_c
};
106 var dfr
= $q
.defer();
107 dfr
.resolve(crmMailingAB
);
111 return crmApi('MailingAB', 'get', {id
: crmMailingAB
.id
})
112 .then(function (abResult
) {
113 if (abResult
.count
!= 1) {
114 throw "Failed to load AB Test";
116 crmMailingAB
.ab
= abResult
.values
[abResult
.id
];
117 return crmMailingAB
._loadMailings();
121 // @return Promise CrmMailingAB
122 save
: function save() {
123 var crmMailingAB
= this;
124 return crmMailingAB
._saveMailings()
126 return crmApi('MailingAB', 'create', crmMailingAB
.ab
)
127 .then(function (abResult
) {
128 if (!crmMailingAB
.id
) {
129 crmMailingAB
.id
= crmMailingAB
.ab
.id
= abResult
.id
;
138 // @return Promise CrmMailingAB
139 // Note: Submission may cause the server state to change. Consider abtest.submit().then(...abtest.load()...)
140 submitTest
: function submitTest() {
141 var crmMailingAB
= this;
145 approval_date
: 'now',
146 scheduled_date
: this.mailings
.a
.scheduled_date
? this.mailings
.a
.scheduled_date
: 'now'
148 return crmApi('MailingAB', 'submit', params
)
150 return crmMailingAB
.load();
153 // Schedule the final mailing
154 // @return Promise CrmMailingAB
155 // Note: Submission may cause the server state to change. Consider abtest.submit().then(...abtest.load()...)
156 submitFinal
: function submitFinal(winner_id
) {
157 var crmMailingAB
= this;
161 winner_id
: winner_id
,
162 approval_date
: 'now',
163 scheduled_date
: this.mailings
.c
.scheduled_date
? this.mailings
.c
.scheduled_date
: 'now'
165 return crmApi('MailingAB', 'submit', params
)
167 return crmMailingAB
.load();
170 // @param mailing Object (per APIv3)
172 'delete': function () {
174 return crmApi('MailingAB', 'delete', {id
: this.id
});
182 // Load mailings A, B, and C (if available)
183 // @return Promise CrmMailingAB
184 _loadMailings
: function _loadMailings() {
185 var crmMailingAB
= this;
187 _
.each(['a', 'b', 'c'], function (mkey
) {
188 if (crmMailingAB
.ab
['mailing_id_' + mkey
]) {
189 todos
[mkey
] = crmMailingMgr
.get(crmMailingAB
.ab
['mailing_id_' + mkey
])
190 .then(function (mailing
) {
191 crmMailingAB
.mailings
[mkey
] = mailing
;
192 crmMailingAB
.attachments
[mkey
] = new CrmAttachments(function () {
193 return {entity_table
: 'civicrm_mailing', entity_id
: crmMailingAB
.ab
['mailing_id_' + mkey
]};
195 return crmMailingAB
.attachments
[mkey
].load();
199 crmMailingAB
.mailings
[mkey
] = crmMailingMgr
.create();
200 crmMailingAB
.attachments
[mkey
] = new CrmAttachments(function () {
201 return {entity_table
: 'civicrm_mailing', entity_id
: crmMailingAB
.ab
['mailing_id_' + mkey
]};
205 return $q
.all(todos
).then(function () {
209 // Save mailings A, B, and C (if available)
210 // @return Promise CrmMailingAB
211 _saveMailings
: function _saveMailings() {
212 var crmMailingAB
= this;
214 var p
= $q
.when(true);
215 _
.each(['a', 'b', 'c'], function (mkey
) {
216 if (!crmMailingAB
.mailings
[mkey
]) {
219 if (crmMailingAB
.ab
['mailing_id_' + mkey
]) {
220 // paranoia: in case caller forgot to manage id on mailing
221 crmMailingAB
.mailings
[mkey
].id
= crmMailingAB
.ab
['mailing_id_' + mkey
];
223 p
= p
.then(function(){
224 return crmMailingMgr
.save(crmMailingAB
.mailings
[mkey
])
226 crmMailingAB
.ab
['mailing_id_' + mkey
] = crmMailingAB
.mailings
[mkey
].id
;
227 return crmMailingAB
.attachments
[mkey
].save();
231 return p
.then(function () {
240 })(angular
, CRM
.$, CRM
._
);