Make it possible to cancel a waitlist offer
authorMagnus Hagander <magnus@hagander.net>
Mon, 9 Jul 2018 11:59:14 +0000 (13:59 +0200)
committerMagnus Hagander <magnus@hagander.net>
Mon, 9 Jul 2018 12:01:40 +0000 (14:01 +0200)
Previously it was only possible to remove a user from the waitlist when
they did not have an active offer, and one had to wait until the offer
expired to to that. Now we can cancel the offer but leave them on the
waitlist, and then decide if we want to cancel the waitlist completely
as a second step.

docs/confreg/graphs/waitlist.dot
docs/confreg/graphs/waitlist.svg
postgresqleu/confreg/views.py
template/confreg/admin_waitlist.html
template/confreg/admin_waitlist_list.inc.html
template/confreg/mail/waitlist_admin_offer_cancel.txt [new file with mode: 0644]

index b1adacff9e83ff3726e76f1c0642fb5df1a48680..6acb3156feba8a0954dc0458fc2b8da4f219f9b1 100644 (file)
@@ -18,6 +18,7 @@ digraph waitlist {
        start -> deleted [label = "No interest in WL", color=green];
 
        waitlist -> offer [label = "&#9993; Offer extended", color=blue];
+       waitlist -> deleted [label ="&#9993; Waitlist canceled", color=blue];
 
        offer -> waitlist [label = "&#9993; Offer expired"];
        offer -> waitlist [label = "&#9993; Offer canceled", color=blue];
index 084d4a4484892b442470a66d9614247b84270e81..51d37236b81bff02f7595834546ab6ffaf91b1b8 100644 (file)
 <!-- Generated by graphviz version 2.38.0 (20140413.2041)
  -->
 <!-- Title: waitlist Pages: 1 -->
-<svg width="512pt" height="474pt"
- viewBox="0.00 0.00 511.79 473.89" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<svg width="601pt" height="474pt"
+ viewBox="0.00 0.00 600.56 473.89" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 469.89)">
 <title>waitlist</title>
-<polygon fill="white" stroke="none" points="-4,4 -4,-469.89 507.787,-469.89 507.787,4 -4,4"/>
+<polygon fill="white" stroke="none" points="-4,4 -4,-469.89 596.563,-469.89 596.563,4 -4,4"/>
 <!-- key -->
 <g id="node1" class="node"><title>key</title>
-<polygon fill="none" stroke="black" points="273,-429.945 132,-429.945 132,-393.945 273,-393.945 273,-429.945"/>
-<text text-anchor="start" x="145.5" y="-415.745" font-family="Times,serif" font-size="14.00"> &#160;&#160;&#160;</text>
-<text text-anchor="start" x="161.5" y="-415.745" font-family="Times,serif" font-size="14.00" fill="blue">Actions by admin</text>
-<text text-anchor="start" x="140" y="-401.745" font-family="Times,serif" font-size="14.00"> &#160;&#160;&#160;</text>
-<text text-anchor="start" x="156" y="-401.745" font-family="Times,serif" font-size="14.00" fill="green">Actions by attendee</text>
+<polygon fill="none" stroke="black" points="317.063,-429.945 176.063,-429.945 176.063,-393.945 317.063,-393.945 317.063,-429.945"/>
+<text text-anchor="start" x="189.563" y="-415.745" font-family="Times,serif" font-size="14.00"> &#160;&#160;&#160;</text>
+<text text-anchor="start" x="205.563" y="-415.745" font-family="Times,serif" font-size="14.00" fill="blue">Actions by admin</text>
+<text text-anchor="start" x="184.063" y="-401.745" font-family="Times,serif" font-size="14.00"> &#160;&#160;&#160;</text>
+<text text-anchor="start" x="200.063" y="-401.745" font-family="Times,serif" font-size="14.00" fill="green">Actions by attendee</text>
 </g>
 <!-- start -->
 <g id="node2" class="node"><title>start</title>
-<ellipse fill="none" stroke="black" cx="344.5" cy="-411.945" rx="53.8905" ry="53.8905"/>
-<text text-anchor="middle" x="344.5" y="-408.245" font-family="Times,serif" font-size="14.00">Registration</text>
+<ellipse fill="none" stroke="black" cx="388.563" cy="-411.945" rx="53.8905" ry="53.8905"/>
+<text text-anchor="middle" x="388.563" y="-408.245" font-family="Times,serif" font-size="14.00">Registration</text>
 </g>
 <!-- waitlist -->
 <g id="node3" class="node"><title>waitlist</title>
-<polygon fill="none" stroke="black" points="240,-307 163,-307 163,-271 240,-271 240,-307"/>
-<text text-anchor="middle" x="201.5" y="-285.3" font-family="Times,serif" font-size="14.00">On waitlist</text>
+<polygon fill="none" stroke="black" points="239.063,-307 162.063,-307 162.063,-271 239.063,-271 239.063,-307"/>
+<text text-anchor="middle" x="200.563" y="-285.3" font-family="Times,serif" font-size="14.00">On waitlist</text>
 </g>
 <!-- start&#45;&gt;waitlist -->
 <g id="edge1" class="edge"><title>start&#45;&gt;waitlist</title>
-<path fill="none" stroke="green" d="M303.854,-376.151C296.745,-370.09 289.414,-363.854 282.5,-358 265.078,-343.249 245.474,-326.787 229.916,-313.755"/>
-<polygon fill="green" stroke="green" points="232.096,-311.016 222.181,-307.281 227.602,-316.384 232.096,-311.016"/>
-<text text-anchor="middle" x="309" y="-328.8" font-family="Times,serif" font-size="14.00">✉ Sign up on WL</text>
+<path fill="none" stroke="green" d="M348.86,-374.915C341.646,-368.991 334.035,-363.121 326.563,-358 301.109,-340.555 270.712,-324.039 246.152,-311.653"/>
+<polygon fill="green" stroke="green" points="247.559,-308.443 237.048,-307.114 244.436,-314.708 247.559,-308.443"/>
+<text text-anchor="middle" x="346.063" y="-328.8" font-family="Times,serif" font-size="14.00">✉ Sign up on WL</text>
 </g>
 <!-- deleted -->
 <g id="node7" class="node"><title>deleted</title>
-<polygon fill="none" stroke="black" points="359.5,-133 215.425,-98.5 503.575,-98.5 359.5,-133"/>
-<text text-anchor="middle" x="359.5" y="-106.3" font-family="Times,serif" font-size="14.00">Waitlist canceled</text>
+<polygon fill="none" stroke="black" points="370.563,-133 226.488,-98.5 514.637,-98.5 370.563,-133"/>
+<text text-anchor="middle" x="370.563" y="-106.3" font-family="Times,serif" font-size="14.00">Waitlist canceled</text>
 </g>
 <!-- start&#45;&gt;deleted -->
 <g id="edge2" class="edge"><title>start&#45;&gt;deleted</title>
-<path fill="none" stroke="green" d="M368.008,-363.225C382.303,-328.899 396.862,-281.229 391.5,-238 387.318,-204.285 377.117,-166.663 369.347,-141.18"/>
-<polygon fill="green" stroke="green" points="372.611,-139.888 366.297,-131.38 365.927,-141.969 372.611,-139.888"/>
-<text text-anchor="middle" x="442.5" y="-241.8" font-family="Times,serif" font-size="14.00">No interest in WL</text>
+<path fill="none" stroke="green" d="M425.65,-372.084C464.935,-325.974 516.9,-247.367 482.563,-184 468.59,-158.215 441.125,-140.099 416.89,-128.364"/>
+<polygon fill="green" stroke="green" points="418.343,-125.18 407.795,-124.176 415.415,-131.538 418.343,-125.18"/>
+<text text-anchor="middle" x="542.563" y="-241.8" font-family="Times,serif" font-size="14.00">No interest in WL</text>
 </g>
 <!-- offer -->
 <g id="node4" class="node"><title>offer</title>
-<polygon fill="none" stroke="black" points="246.5,-220 166.5,-220 166.5,-184 246.5,-184 246.5,-220"/>
-<text text-anchor="middle" x="206.5" y="-198.3" font-family="Times,serif" font-size="14.00">Offer made</text>
+<polygon fill="none" stroke="black" points="195.563,-220 115.563,-220 115.563,-184 195.563,-184 195.563,-220"/>
+<text text-anchor="middle" x="155.563" y="-198.3" font-family="Times,serif" font-size="14.00">Offer made</text>
 </g>
 <!-- waitlist&#45;&gt;offer -->
 <g id="edge3" class="edge"><title>waitlist&#45;&gt;offer</title>
-<path fill="none" stroke="blue" d="M162.668,-284.997C119.999,-280.159 60.3751,-267.931 83.5,-238 102.877,-212.92 122.042,-228.761 152.5,-220 153.917,-219.592 155.353,-219.174 156.801,-218.748"/>
-<polygon fill="blue" stroke="blue" points="157.891,-222.075 166.463,-215.848 155.879,-215.371 157.891,-222.075"/>
-<text text-anchor="middle" x="131.5" y="-241.8" font-family="Times,serif" font-size="14.00">✉ Offer extended</text>
+<path fill="none" stroke="blue" d="M225.557,-270.97C236.355,-261.449 245.002,-249.264 237.563,-238 230.017,-226.575 217.896,-218.867 205.263,-213.671"/>
+<polygon fill="blue" stroke="blue" points="206.164,-210.275 195.569,-210.167 203.784,-216.858 206.164,-210.275"/>
+<text text-anchor="middle" x="287.563" y="-241.8" font-family="Times,serif" font-size="14.00">✉ Offer extended</text>
 </g>
-<!-- offer&#45;&gt;waitlist -->
-<g id="edge4" class="edge"><title>offer&#45;&gt;waitlist</title>
-<path fill="none" stroke="black" d="M204.226,-220.061C203.553,-225.755 202.892,-232.142 202.5,-238 202.009,-245.334 201.733,-253.285 201.584,-260.643"/>
-<polygon fill="black" stroke="black" points="198.081,-260.812 201.446,-270.858 205.081,-260.907 198.081,-260.812"/>
-<text text-anchor="middle" x="246.5" y="-241.8" font-family="Times,serif" font-size="14.00">✉ Offer expired</text>
+<!-- waitlist&#45;&gt;deleted -->
+<g id="edge4" class="edge"><title>waitlist&#45;&gt;deleted</title>
+<path fill="none" stroke="blue" d="M239.379,-282.853C275.511,-277.27 325.797,-267.209 339.563,-253 367.877,-223.772 372.82,-175.017 372.601,-142.936"/>
+<polygon fill="blue" stroke="blue" points="376.095,-142.66 372.355,-132.747 369.098,-142.829 376.095,-142.66"/>
+<text text-anchor="middle" x="424.063" y="-198.3" font-family="Times,serif" font-size="14.00">✉ Waitlist canceled</text>
 </g>
 <!-- offer&#45;&gt;waitlist -->
 <g id="edge5" class="edge"><title>offer&#45;&gt;waitlist</title>
-<path fill="none" stroke="blue" d="M246.572,-211.183C274.561,-218.865 304.594,-232.312 290.5,-253 281.133,-266.749 265.463,-275.097 249.86,-280.166"/>
-<polygon fill="blue" stroke="blue" points="248.867,-276.81 240.21,-282.917 250.786,-283.541 248.867,-276.81"/>
-<text text-anchor="middle" x="340.5" y="-241.8" font-family="Times,serif" font-size="14.00">✉ Offer canceled</text>
+<path fill="none" stroke="black" d="M115.525,-215.848C110.829,-217.283 106.096,-218.696 101.563,-220 71.1046,-228.761 51.9391,-212.92 32.5626,-238 28.4867,-243.276 28.3566,-247.828 32.5626,-253 47.3847,-271.228 107.708,-280.281 151.842,-284.545"/>
+<polygon fill="black" stroke="black" points="151.555,-288.033 161.832,-285.456 152.191,-281.062 151.555,-288.033"/>
+<text text-anchor="middle" x="76.5626" y="-241.8" font-family="Times,serif" font-size="14.00">✉ Offer expired</text>
+</g>
+<!-- offer&#45;&gt;waitlist -->
+<g id="edge6" class="edge"><title>offer&#45;&gt;waitlist</title>
+<path fill="none" stroke="blue" d="M143.178,-220.429C137.716,-230.405 133.716,-242.905 139.563,-253 143.016,-258.963 147.912,-263.998 153.445,-268.224"/>
+<polygon fill="blue" stroke="blue" points="151.65,-271.233 161.916,-273.851 155.523,-265.402 151.65,-271.233"/>
+<text text-anchor="middle" x="186.563" y="-241.8" font-family="Times,serif" font-size="14.00">✉ Offer canceled</text>
 </g>
 <!-- invoice -->
 <g id="node5" class="node"><title>invoice</title>
-<polygon fill="none" stroke="black" points="128,-128 15,-128 15,-92 128,-92 128,-128"/>
-<text text-anchor="middle" x="71.5" y="-106.3" font-family="Times,serif" font-size="14.00">Invoice generated</text>
+<polygon fill="none" stroke="black" points="152.063,-128 39.0626,-128 39.0626,-92 152.063,-92 152.063,-128"/>
+<text text-anchor="middle" x="95.5626" y="-106.3" font-family="Times,serif" font-size="14.00">Invoice generated</text>
 </g>
 <!-- offer&#45;&gt;invoice -->
-<g id="edge7" class="edge"><title>offer&#45;&gt;invoice</title>
-<path fill="none" stroke="green" d="M180.79,-183.86C159.489,-169.66 129.036,-149.357 105.683,-133.789"/>
-<polygon fill="green" stroke="green" points="107.376,-130.711 97.1145,-128.076 103.494,-136.536 107.376,-130.711"/>
-<text text-anchor="middle" x="189.5" y="-154.8" font-family="Times,serif" font-size="14.00">Accepted spot</text>
+<g id="edge8" class="edge"><title>offer&#45;&gt;invoice</title>
+<path fill="none" stroke="green" d="M128.394,-183.684C122.139,-178.626 116.022,-172.646 111.563,-166 105.947,-157.631 102.271,-147.269 99.8775,-137.803"/>
+<polygon fill="green" stroke="green" points="103.296,-137.05 97.7534,-128.02 96.4549,-138.535 103.296,-137.05"/>
+<text text-anchor="middle" x="150.563" y="-154.8" font-family="Times,serif" font-size="14.00">Accepted spot</text>
 </g>
 <!-- offer&#45;&gt;deleted -->
-<g id="edge6" class="edge"><title>offer&#45;&gt;deleted</title>
-<path fill="none" stroke="green" d="M235.638,-183.86C260.799,-169.06 297.228,-147.63 324.07,-131.841"/>
-<polygon fill="green" stroke="green" points="325.93,-134.808 332.775,-126.721 322.381,-128.774 325.93,-134.808"/>
-<text text-anchor="middle" x="325.5" y="-154.8" font-family="Times,serif" font-size="14.00">Declined spot</text>
+<g id="edge7" class="edge"><title>offer&#45;&gt;deleted</title>
+<path fill="none" stroke="green" d="M195.75,-184.177C233.285,-168.465 289.141,-145.083 327.56,-129.001"/>
+<polygon fill="green" stroke="green" points="329.057,-132.169 336.93,-125.079 326.354,-125.712 329.057,-132.169"/>
+<text text-anchor="middle" x="306.563" y="-154.8" font-family="Times,serif" font-size="14.00">Declined spot</text>
 </g>
 <!-- invoice&#45;&gt;waitlist -->
-<g id="edge9" class="edge"><title>invoice&#45;&gt;waitlist</title>
-<path fill="none" stroke="black" d="M64.7193,-128.391C54.0105,-159.118 37.8388,-222.624 73.5,-253 95.4854,-271.727 126.632,-280.506 152.696,-284.59"/>
-<polygon fill="black" stroke="black" points="152.389,-288.08 162.774,-285.98 153.346,-281.146 152.389,-288.08"/>
-<text text-anchor="middle" x="103" y="-198.3" font-family="Times,serif" font-size="14.00">✉ Invoice expired</text>
+<g id="edge10" class="edge"><title>invoice&#45;&gt;waitlist</title>
+<path fill="none" stroke="black" d="M62.8045,-128.253C42.8051,-140.771 18.9562,-159.745 7.56259,-184 -5.86584,-212.587 -0.662617,-233.994 24.5626,-253 44.2415,-267.827 106.796,-277.694 151.728,-283.069"/>
+<polygon fill="black" stroke="black" points="151.542,-286.571 161.878,-284.244 152.347,-279.617 151.542,-286.571"/>
+<text text-anchor="middle" x="57.0626" y="-198.3" font-family="Times,serif" font-size="14.00">✉ Invoice expired</text>
 </g>
 <!-- completed -->
 <g id="node6" class="node"><title>completed</title>
-<polygon fill="none" stroke="black" points="143,-36 0,-36 0,-0 143,-0 143,-36"/>
-<text text-anchor="middle" x="71.5" y="-14.3" font-family="Times,serif" font-size="14.00">Registration completed</text>
+<polygon fill="none" stroke="black" points="167.063,-36 24.0626,-36 24.0626,-0 167.063,-0 167.063,-36"/>
+<text text-anchor="middle" x="95.5626" y="-14.3" font-family="Times,serif" font-size="14.00">Registration completed</text>
 </g>
 <!-- invoice&#45;&gt;completed -->
-<g id="edge8" class="edge"><title>invoice&#45;&gt;completed</title>
-<path fill="none" stroke="green" d="M71.5,-91.6471C71.5,-78.8228 71.5,-61.1075 71.5,-46.3815"/>
-<polygon fill="green" stroke="green" points="75.0001,-46.2996 71.5,-36.2996 68.0001,-46.2997 75.0001,-46.2996"/>
-<text text-anchor="middle" x="112.5" y="-57.8" font-family="Times,serif" font-size="14.00">✉ Paid invoice</text>
+<g id="edge9" class="edge"><title>invoice&#45;&gt;completed</title>
+<path fill="none" stroke="green" d="M95.5626,-91.6471C95.5626,-78.8228 95.5626,-61.1075 95.5626,-46.3815"/>
+<polygon fill="green" stroke="green" points="99.0627,-46.2996 95.5626,-36.2996 92.0627,-46.2997 99.0627,-46.2996"/>
+<text text-anchor="middle" x="136.563" y="-57.8" font-family="Times,serif" font-size="14.00">✉ Paid invoice</text>
 </g>
 </g>
 </svg>
index 19f3b7b215fc0f88d65a54430ef187c83e2e71f2..a0a4156591b6d95e4ec7809766c383f9ab584f60 100644 (file)
@@ -2645,27 +2645,57 @@ def admin_waitlist_cancel(request, urlname, wlid):
 
        wl = get_object_or_404(RegistrationWaitlistEntry, pk=wlid, registration__conference=conference)
        reg = wl.registration
-       wl.delete()
-
-       send_simple_mail(reg.conference.contactaddr,
-                                        reg.conference.contactaddr,
-                                        'Waitlist cancel',
-                                        u'User {0} {1} <{2}> removed from the waitlist by {3}.'.format(reg.firstname, reg.lastname, reg.email, request.user),
-                                        sendername=reg.conference.conferencename)
+       if wl.offeredon:
+               # Active offer means we are moving this entry back onto the waitlist
+               RegistrationWaitlistHistory(waitlist=wl,
+                                                                       text="Offer canceled by {0}".format(request.user.username)).save()
+               wl.offeredon = None
+               wl.offerexpires = None
+               wl.enteredon = datetime.now()
+               wl.save()
+
+               send_simple_mail(reg.conference.contactaddr,
+                                                reg.conference.contactaddr,
+                                                'Waitlist offer cancel',
+                                                u'Waitlist offer for user {0} {1} <{2}> canceled by {3}. User remains on waitlist.'.format(reg.firstname, reg.lastname, reg.email, request.user),
+                                                sendername=reg.conference.conferencename)
+
+               send_template_mail(reg.conference.contactaddr,
+                                                  reg.email,
+                                                  'Waitlist offer canceled',
+                                                  'confreg/mail/waitlist_admin_offer_cancel.txt',
+                                                  {
+                                                          'conference': conference,
+                                                          'reg': reg,
+                                                  },
+                                                  sendername=reg.conference.conferencename,
+                                                  receivername=reg.fullname,
+               )
+               messages.info(request, "Waitlist offer canceled.")
 
-       send_template_mail(reg.conference.contactaddr,
-                                          reg.email,
-                                          'Waitlist canceled',
-                                          'confreg/mail/waitlist_admin_cancel.txt',
-                                          {
-                                                  'conference': conference,
-                                                  'reg': reg,
-                                          },
-                                          sendername=reg.conference.conferencename,
-                                          receivername=reg.fullname,
-                                          )
+       else:
+               # No active offer means we are canceling the entry completely
+               wl.delete()
+
+               send_simple_mail(reg.conference.contactaddr,
+                                                reg.conference.contactaddr,
+                                                'Waitlist cancel',
+                                                u'User {0} {1} <{2}> removed from the waitlist by {3}.'.format(reg.firstname, reg.lastname, reg.email, request.user),
+                                                sendername=reg.conference.conferencename)
+
+               send_template_mail(reg.conference.contactaddr,
+                                                  reg.email,
+                                                  'Waitlist canceled',
+                                                  'confreg/mail/waitlist_admin_cancel.txt',
+                                                  {
+                                                          'conference': conference,
+                                                          'reg': reg,
+                                                  },
+                                                  sendername=reg.conference.conferencename,
+                                                  receivername=reg.fullname,
+               )
 
-       messages.info(request, "Waitlist entry removed.")
+               messages.info(request, "Waitlist entry removed.")
        return HttpResponseRedirect("../../")
 
 
index 8cff899a0f9ef29bb83f0437c9d312fe26698ecf..db0c4a325a6f865059a0b0a80939acb0d56ee613 100644 (file)
@@ -26,6 +26,12 @@ function cancelWaitlist(id) {
       document.location.href = 'cancel/' + id + '/';
    }
 }
+
+function cancelOffer(id) {
+   if (confirm('Are you really sure you want to cancel this waitlist offer?\nRegistration will return to regular waitlist, and a notification sent.')) {
+      document.location.href = 'cancel/' + id + '/';
+   }
+}
 </script>
 {%endblock%}
 
index ac36a69a55201bbe3d934e6a7548e774344771f4..fa8d519ee85ec74aa30e09c9725b3377f6699794 100644 (file)
@@ -28,7 +28,7 @@
     <td style="white-space: nowrap"><span onClick="showDialog({{w.registration.id}})" class="dlgClickable ui-icon ui-icon-circle-plus" style="display: inline-block"></span>
 {%if w.registration.payconfirmedat%}Registered{%elif w.offeredon%}Offered{%if w.registration.invoice%} (with invoice){%endif%}{%else%}Pending ({{w.offers_made}} offers){%endif%}</td>
 {%if waitlist_type == "waitlist_active" %}
-    {%if not w.offeredon and not w.registration.payconfirmedat%}<td style="white-space: nowrap;"><input type="checkbox" name="reg_{{w.registration.id}}" value="1"{%if w.registration.id in form.reg_list%} CHECKED{%endif%}> offer<br><a href="javascript:cancelWaitlist({{w.pk}})" class="btn btn-default btn-xs">Cancel</a></td>{%else%}<td></td>{%endif%}
+    {%if not w.offeredon and not w.registration.payconfirmedat%}<td style="white-space: nowrap;"><input type="checkbox" name="reg_{{w.registration.id}}" value="1"{%if w.registration.id in form.reg_list%} CHECKED{%endif%}> offer<br><a href="javascript:cancelWaitlist({{w.pk}})" class="btn btn-default btn-xs">Cancel</a></td>{%else%}<td><a href="javascript:cancelOffer({{w.pk}})" class="btn btn-default btn-xs">Cancel</a></td>{%endif%}
 {%endif%}
   </tr>
 {%endfor%}
diff --git a/template/confreg/mail/waitlist_admin_offer_cancel.txt b/template/confreg/mail/waitlist_admin_offer_cancel.txt
new file mode 100644 (file)
index 0000000..d880007
--- /dev/null
@@ -0,0 +1,20 @@
+Hello!
+
+Your offer on the waitlist for {{conference.conferencename}}
+has been canceled by an administrator.
+
+Your registration has been returned to the regular waitlist, and may
+receive further offers in the future.
+
+If you are no longer interested in attending the conference, please
+go to
+
+{{sitebase}}/events/{{conference.urlname}}/register/confirm/
+
+and remove yourself from the waitlist. That will make our processing
+of waitlist entries for other attendees much smoother, and you will
+no longer receive emails about it from us.
+
+If you wish to remain on the waitlist, you do not need to do
+anything. If another seat shows up, an new email outlining this
+offer and expiry time will be sent to you.