Disallow creating campaigns starting more than 30 days in the future.

That can create situations where the authorization hold expires
before being charged.
This commit is contained in:
Brian Simpson
2014-04-24 05:44:42 -04:00
parent 1af36dad3f
commit 41129145db
4 changed files with 50 additions and 20 deletions

View File

@@ -21,6 +21,7 @@
###############################################################################
from datetime import datetime, timedelta
from babel.dates import format_date
from babel.numbers import format_number
import json
import urllib
@@ -705,6 +706,16 @@ class PromoteApiController(ApiController):
errors.DATE_TOO_LATE, errors.BAD_DATE_RANGE)):
return
# check that start is not so late that authorization hold will expire
if not c.user_is_sponsor:
max_start = promote.get_max_startdate()
if start > max_start:
c.errors.add(errors.DATE_TOO_LATE,
msg_params={'day': max_start.strftime("%m/%d/%Y")},
field='startdate')
form.has_errors('startdate', errors.DATE_TOO_LATE)
return
# Limit the number of PromoCampaigns a Link can have
# Note that the front end should prevent the user from getting
# this far
@@ -828,6 +839,15 @@ class PromoteApiController(ApiController):
if campaign_has_oversold_error(form, campaign):
return
# check that start is not so late that authorization hold will expire
max_start = promote.get_max_startdate()
if campaign.start_date > max_start:
msg = _("please change campaign start date to %(date)s or earlier")
date = format_date(max_start, format="short", locale=c.locale)
msg %= {'date': date}
form.set_html(".status", msg)
return
address_modified = not pay_id or edit
form_has_errors = False
if address_modified:

View File

@@ -3484,26 +3484,29 @@ class PromoteLinkForm(Templated):
now = promote.promo_datetime_now()
if c.user_is_sponsor:
mindate = now
min_start = now
elif promote.is_accepted(link):
mindate = make_offset_date(now, 1, business_days=True)
min_start = make_offset_date(now, 1, business_days=True)
else:
mindate = make_offset_date(now, g.min_promote_future,
business_days=True)
min_start = make_offset_date(now, g.min_promote_future,
business_days=True)
if c.user_is_sponsor:
max_days = 366
max_end = now + datetime.timedelta(days=366)
else:
max_days = g.max_promote_future
max_end = now + datetime.timedelta(days=g.max_promote_future)
maxstart = now + datetime.timedelta(max_days-1)
maxend = maxstart + datetime.timedelta(days=1)
self.maxstart = maxstart.strftime("%m/%d/%Y")
self.maxend = maxend.strftime("%m/%d/%Y")
if c.user_is_sponsor:
max_start = max_end - datetime.timedelta(days=1)
else:
max_start = promote.get_max_startdate()
self.startdate = mindate.strftime("%m/%d/%Y")
enddate = mindate + datetime.timedelta(days=2)
self.enddate = enddate.strftime("%m/%d/%Y")
self.max_start = max_start.strftime("%m/%d/%Y")
self.max_end = max_end.strftime("%m/%d/%Y")
self.min_start = self.default_start = min_start.strftime("%m/%d/%Y")
default_end = min_start + datetime.timedelta(days=2)
self.default_end = default_end.strftime("%m/%d/%Y")
self.subreddit_selector = SubredditSelector()
@@ -3557,8 +3560,8 @@ class PromoteLinkForm(Templated):
srnames.update(names)
srs = Subreddit._by_name(srnames)
srs[''] = Frontpage
inv_start = mindate
inv_end = mindate + datetime.timedelta(days=14)
inv_start = min_start
inv_end = min_start + datetime.timedelta(days=14)
sr_inventory = inventory.get_available_pageviews(
srs.values(), inv_start, inv_end, datestr=True)

View File

@@ -398,6 +398,13 @@ def promo_datetime_now(offset=None):
return now
def get_max_startdate():
# authorization hold happens now but expires after 30 days. charge
# happens 1 day before the campaign launches. the latest a campaign
# can start is 30 days from now (it will get charged in 29 days).
return promo_datetime_now() + timedelta(days=30)
def accept_promotion(link):
update_promote_status(link, PROMOTE_STATUS.accepted)

View File

@@ -298,10 +298,10 @@ ${self.javascript_setup()}
<tr>
<th>${_("start")}</th>
<td class="prefright">
<input type="hidden" id="date-min" value="${thing.startdate}">
<input type="hidden" id="date-start-max" value="${thing.maxstart}">
<input type="hidden" id="date-end-max" value="${thing.maxend}">
<%self:datepicker name="startdate", value="${thing.startdate}"
<input type="hidden" id="date-min" value="${thing.min_start}">
<input type="hidden" id="date-start-max" value="${thing.max_start}">
<input type="hidden" id="date-end-max" value="${thing.max_end}">
<%self:datepicker name="startdate", value="${thing.default_start}"
minDateSrc="date-min" maxDateSrc="date-start-max"
initfuncname="init_startdate">
function(elem) {
@@ -314,7 +314,7 @@ ${self.javascript_setup()}
<tr>
<th>${_("end")}</th>
<td class="prefright">
<%self:datepicker name="enddate", value="${thing.enddate}"
<%self:datepicker name="enddate", value="${thing.default_end}"
minDateSrc="startdate" maxDateSrc="date-end-max"
initfuncname="init_enddate" min_date_offset="86400000">
function(elem) { r.sponsored.on_date_change(); }