backoffice: make it possible to send back tracking code from 360 view (#8697)

This commit is contained in:
Frédéric Péters 2015-11-15 14:46:55 +01:00
parent 146f237c03
commit 2461200689
5 changed files with 164 additions and 4 deletions

View File

@ -23,7 +23,8 @@ from wcs.categories import Category
from wcs.formdef import FormDef
from wcs import fields
from utilities import get_app, login, create_temporary_pub, clean_temporary_pub
from utilities import (get_app, login, create_temporary_pub,
clean_temporary_pub, emails, sms_mocking)
def pytest_generate_tests(metafunc):
if 'pub' in metafunc.fixturenames:
@ -1268,3 +1269,51 @@ def test_360_user_view(pub):
resp = app.get('/backoffice/management/users/%s/' % user.id)
for item in to_match:
assert item in resp.body
def test_360_user_view_tracking_code(pub):
if not pub.is_using_postgresql():
pytest.skip('this requires SQL')
return
emails.empty()
sms_mocking.empty()
user = create_user(pub)
create_environment(pub)
app = login(get_app(pub))
formdef = FormDef.get_by_urlname('form-title')
form_class = formdef.data_class()
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
number31.user_id = user.id
number31.store()
resp = app.get('/backoffice/management/users/%s/' % user.id)
assert not 'Send tracking code' in resp.body
formdef.enable_tracking_codes = True
formdef.store()
user_view_resp = app.get('/backoffice/management/users/%s/' % user.id)
assert 'Send tracking code' in user_view_resp.body
pub.cfg['sms'] = {'mode': 'none'}
pub.write_cfg()
resp = user_view_resp.click('Send tracking code')
assert not 'sms' in resp.form.fields
assert resp.form['email'].value == user.email
resp = resp.form.submit()
resp = resp.follow()
assert emails.count() == 1
assert emails.get('Tracking Code reminder')['email_rcpt'] == [user.email]
assert form_class.get(number31.id).tracking_code in emails.get('Tracking Code reminder')['payload']
pub.cfg['sms'] = {'mode': 'xx'}
pub.write_cfg()
resp = user_view_resp.click('Send tracking code', index=0)
resp.form['method'].value = 'SMS'
resp.form['sms'].value = '0123456789'
resp = resp.form.submit()
resp = resp.follow()
assert sms_mocking.sms[-1]['destinations'] == ['0123456789']
assert form_class.get(number31.id).tracking_code in sms_mocking.sms[-1]['text']

View File

@ -765,6 +765,7 @@ def test_form_empty_tracking_code(pub):
resp = resp.follow(status=404)
def test_form_tracking_code_email(pub):
emails.empty()
formdef = create_formdef()
formdef.data_class().wipe()
formdef.fields = [fields.StringField(id='0', label='string')]

View File

@ -604,6 +604,7 @@ def test_timeout_then_remove(two_pubs):
assert not str(formdata_id) in [str(x) for x in formdef.data_class().keys()]
def test_sms(pub):
pub.cfg['sms'] = {'mode': 'xxx'}
formdef = FormDef()
formdef.name = 'baz'
formdef.fields = []

View File

@ -241,10 +241,15 @@ http_requests = HttpRequestsMocking()
class SMSMocking(wcs.qommon.sms.MobytSMS):
def __init__(self):
wcs.qommon.sms.SMS.get_sms_class = classmethod(lambda x, y: self)
qommon.sms.SMS.get_sms_class = classmethod(lambda x, y: self)
wcs.qommon.sms.SMS.get_sms_class = self.get_sms_class
qommon.sms.SMS.get_sms_class = self.get_sms_class
self.sms = []
def get_sms_class(self, mode):
if mode == 'none':
return None
return self
def send(self, sender, destinations, text, quality=None):
self.sms.append({'sender': sender, 'destinations': destinations,
'text': text})

View File

@ -29,13 +29,18 @@ from quixote import get_session, get_publisher, get_request, get_response, redir
from quixote.directory import Directory
from quixote.html import TemplateIO, htmltext
from qommon.admin.emails import EmailsDirectory
from qommon.admin.menu import command_icon
from qommon.backoffice.menu import html_top
from qommon.backoffice.listing import pagination_links
from qommon import misc, get_logger
from qommon.afterjobs import AfterJob
from qommon import emails
from qommon import errors
from qommon import ezt
from qommon import ods
from qommon.form import *
from qommon.sms import SMS
from qommon.storage import (Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or,
Intersects, ILike, FtsMatch)
@ -48,10 +53,99 @@ from wcs.formdef import FormDef
from wcs.roles import logged_users_role
class SendCodeFormdefDirectory(Directory):
formdef = None
def __init__(self, formdef):
self.formdef = formdef
def _q_lookup(self, formdata_id):
html_top('management', _('Management'))
formdata = self.formdef.data_class().get(formdata_id)
submitter_email = formdata.formdef.get_submitter_email(formdata)
mail_subject = EmailsDirectory.get_subject('tracking-code-reminder')
mail_body = EmailsDirectory.get_body('tracking-code-reminder')
form = Form()
form.add(TextWidget, 'text', title=_('Message'), required=True,
cols=60, rows=5, value=mail_body)
form.add(EmailWidget, 'email', title=_('Email'), required=False,
value=submitter_email)
sms_class = None
if get_publisher().use_sms_feature:
sms_cfg = get_cfg('sms', {})
mode = sms_cfg.get('mode', 'none')
sms_class = SMS.get_sms_class(mode)
if sms_class:
form.add(StringWidget, 'sms', title=_('SMS Number'), required=False)
form.add(RadiobuttonsWidget, 'method',
options=[('email', _('Email')),
('sms', _('SMS'))],
value='email',
required=True)
form.add_submit('submit', _('Send'))
form.add_submit('cancel', _('Cancel'))
if not form.is_submitted() or form.has_errors():
r = TemplateIO(html=True)
r += htmltext('<h2>%s</h2>') % _('Send tracking code')
r += form.render()
return r.getvalue()
if not formdata.tracking_code:
tracking_code = get_publisher().tracking_code_class()
tracking_code.formdata = formdata # this stores both objects
msg = form.get_widget('text').parse()
data = {
'form_tracking_code': formdata.tracking_code,
'tracking_code': formdata.tracking_code,
'email': form.get_widget('email').parse(),
}
data.update(self.formdef.get_substitution_variables(minimal=True))
msg_template = ezt.Template(compress_whitespace=False)
msg_template.parse(msg)
fd = cStringIO.StringIO()
msg_template.generate(fd, data)
msg_body = fd.getvalue()
if sms_class and form.get_widget('method').parse() == 'sms':
# send sms
sitename = get_cfg('misc', {}).get('sitename') or 'w.c.s.'
sender = sms_cfg.get('sender', sitename)[:11]
message = msg_body
try:
sms_class.send(sender, [form.get_widget('sms').parse()], message)
except errors.SMSError, e:
get_logger().error(e)
get_session().message = ('info', _('SMS with tracking code sent to the user'))
else:
# send mail
emails.ezt_email(mail_subject, msg_body,
mail_body_data=data,
email_rcpt=form.get_widget('email').parse())
get_session().message = ('info', _('Email with tracking code sent to the user'))
return redirect('../..')
class SendCodeDirectory(Directory):
def _q_lookup(self, component):
try:
formdef = FormDef.get_by_urlname(component)
if not formdef.enable_tracking_codes:
raise errors.TraversalError()
return SendCodeFormdefDirectory(formdef)
except KeyError:
raise errors.TraversalError()
class UserViewDirectory(Directory):
_q_exports = ['']
_q_exports = ['', 'sendcode']
sendcode = SendCodeDirectory()
user = None
def __init__(self, user):
@ -70,6 +164,8 @@ class UserViewDirectory(Directory):
formdatas = sql.AnyFormData.select(criterias, order_by='receipt_time')
r = TemplateIO(html=True)
r += get_session().display_message()
r += htmltext('<div class="bo-block">')
r += htmltext('<h2>%s</h2>') % self.user.display_name
formdef = UserFieldsFormDef()
@ -125,6 +221,14 @@ class UserViewDirectory(Directory):
formdata.get_url(backoffice=True),
formdata.formdef.name,
submit_date, status_label))
if formdata.formdef.enable_tracking_codes:
r += htmltext('<p class="commands">')
r += command_icon('sendcode/%s/%s' %
(formdata.formdef.url_name, formdata.id),
'export',
label=_('Send tracking code'),
popup=True)
r += htmltext('</p>')
r += htmltext('</ul>')
r += htmltext('</div>')
r += htmltext('</div>')