Merge branch 'relaunch' of github.com:Gluejar/regluit into relaunch
commit
839a864149
|
@ -210,6 +210,47 @@ class Campaign(models.Model):
|
|||
except:
|
||||
return u"Campaign %s (no associated work)" % self.name
|
||||
|
||||
def clone(self):
|
||||
"""use a previous UNSUCCESSFUL campaign's data as the basis for a new campaign"""
|
||||
if self.clonable():
|
||||
old_managers= self.managers.all()
|
||||
|
||||
# copy custom premiums
|
||||
new_premiums= self.premiums.filter(type='CU')
|
||||
|
||||
# setting pk to None will insert new copy http://stackoverflow.com/a/4736172/7782
|
||||
self.pk = None
|
||||
self.status = 'INITIALIZED'
|
||||
|
||||
# set deadline far in future -- presumably RH will set deadline to proper value before campaign launched
|
||||
self.deadline = date_today() + timedelta(days=int(settings.UNGLUEIT_LONGEST_DEADLINE))
|
||||
|
||||
# allow created, activated dates to be autoset by db
|
||||
self.created = None
|
||||
self.name = 'copy of %s' % self.name
|
||||
self.activated = None
|
||||
self.update_left()
|
||||
self.save()
|
||||
self.managers=old_managers
|
||||
|
||||
# clone associated premiums
|
||||
for premium in new_premiums:
|
||||
premium.pk=None
|
||||
premium.created = None
|
||||
premium.campaign = self
|
||||
premium.save()
|
||||
return self
|
||||
else:
|
||||
return None
|
||||
|
||||
def clonable(self):
|
||||
"""campaign clonable if it's UNSUCCESSFUL and is the last campaign associated with a Work"""
|
||||
|
||||
if self.status == 'UNSUCCESSFUL' and self.work.last_campaign().id==self.id:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@property
|
||||
def launchable(self):
|
||||
may_launch=True
|
||||
|
@ -341,7 +382,9 @@ class Campaign(models.Model):
|
|||
@property
|
||||
def supporters_count(self):
|
||||
# avoid transmitting the whole list if you don't need to; let the db do the count.
|
||||
return self.transactions().filter(status=TRANSACTION_STATUS_ACTIVE).values_list('user', flat=True).distinct().count()
|
||||
active = self.transactions().filter(status=TRANSACTION_STATUS_ACTIVE).values_list('user', flat=True).distinct().count()
|
||||
complete = self.transactions().filter(status=TRANSACTION_STATUS_COMPLETE).values_list('user', flat=True).distinct().count()
|
||||
return active+complete
|
||||
|
||||
def transaction_to_recharge(self, user):
|
||||
"""given a user, return the transaction to be recharged if there is one -- None otherwise"""
|
||||
|
|
|
@ -14,7 +14,7 @@ from django.contrib.sites.models import Site
|
|||
from django.http import Http404
|
||||
|
||||
from regluit.payment.models import Transaction
|
||||
from regluit.core.models import Campaign, Work, UnglueitError, Edition, RightsHolder, Claim, Key, Ebook
|
||||
from regluit.core.models import Campaign, Work, UnglueitError, Edition, RightsHolder, Claim, Key, Ebook, Premium
|
||||
from regluit.core import bookloader, models, search, goodreads, librarything
|
||||
from regluit.core import isbn
|
||||
from regluit.payment.parameters import PAYMENT_TYPE_AUTHORIZATION
|
||||
|
@ -388,6 +388,8 @@ class CampaignTests(TestCase):
|
|||
|
||||
w = Work()
|
||||
w.save()
|
||||
w2 = Work()
|
||||
w2.save()
|
||||
# INITIALIZED
|
||||
c1 = Campaign(target=D('1000.00'),deadline=datetime(2013,1,1),work=w)
|
||||
c1.save()
|
||||
|
@ -402,6 +404,8 @@ class CampaignTests(TestCase):
|
|||
rh.save()
|
||||
cl = Claim(rights_holder = rh, work = w, user = u, status = 'active')
|
||||
cl.save()
|
||||
cl2 = Claim(rights_holder = rh, work = w2, user = u, status = 'active')
|
||||
cl2.save()
|
||||
c2.activate()
|
||||
self.assertEqual(c2.status, 'ACTIVE')
|
||||
# SUSPENDED
|
||||
|
@ -414,14 +418,25 @@ class CampaignTests(TestCase):
|
|||
# should not let me suspend a campaign that hasn't been initialized
|
||||
self.assertRaises(UnglueitError, c1.suspend, "for testing")
|
||||
# UNSUCCESSFUL
|
||||
c3 = Campaign(target=D('1000.00'),deadline=now() - timedelta(days=1),work=w)
|
||||
c3 = Campaign(target=D('1000.00'),deadline=now() - timedelta(days=1),work=w2)
|
||||
c3.save()
|
||||
c3.activate()
|
||||
self.assertEqual(c3.status, 'ACTIVE')
|
||||
# at this point, since the deadline has passed, the status should change and be UNSUCCESSFUL
|
||||
self.assertTrue(c3.update_status())
|
||||
self.assertEqual(c3.status, 'UNSUCCESSFUL')
|
||||
|
||||
|
||||
# premiums
|
||||
pr1= Premium(type='CU', campaign=c3, amount=10, description='botsnack', limit=1)
|
||||
pr1.save()
|
||||
self.assertEqual(pr1.premium_remaining,1)
|
||||
|
||||
#cloning (note we changed c3 to w2 to make it clonable)
|
||||
c7= c3.clone()
|
||||
self.assertEqual(c7.status, 'INITIALIZED')
|
||||
self.assertEqual(c7.premiums.all()[0].description , 'botsnack')
|
||||
|
||||
|
||||
# SUCCESSFUL
|
||||
c4 = Campaign(target=D('1000.00'),deadline=now() - timedelta(days=1),work=w)
|
||||
c4.save()
|
||||
|
|
|
@ -164,6 +164,9 @@ class UserData(forms.Form):
|
|||
return username
|
||||
raise forms.ValidationError(_("Your username is already "+username))
|
||||
|
||||
class CloneCampaignForm(forms.Form):
|
||||
campaign_id = forms.IntegerField(required = True, widget = forms.HiddenInput)
|
||||
|
||||
class OpenCampaignForm(forms.ModelForm):
|
||||
managers = AutoCompleteSelectMultipleField(
|
||||
OwnerLookup,
|
||||
|
|
|
@ -208,8 +208,9 @@ Please fix the following before launching your campaign:
|
|||
{{ form.deadline.errors }}<span style="display: none">{{ form.deadline }}</span>
|
||||
{% endifnotequal %}
|
||||
|
||||
<h3>Email address</h3>
|
||||
<p>Enter the email address we should contact you at for issues relating to managing this campaign.</p>
|
||||
<h3>e-mail contact address</h3>
|
||||
<p>Enter the email address where notifications about this campaign should be sent. If your campaign succeeds, this email needs to work if you want to get paid!</p>
|
||||
|
||||
|
||||
<p>{{ form.paypal_receiver.errors }}{{ form.paypal_receiver }}</p>
|
||||
|
||||
|
|
|
@ -20,21 +20,33 @@
|
|||
Any questions not covered here? Please email us at <a href="mailto:rights@gluejar.com">rights@gluejar.com</a>.
|
||||
</div></div>
|
||||
|
||||
{% if request.user.campaigns.all %}
|
||||
{% if campaigns %}
|
||||
<h2>Campaigns You Manage</h2>
|
||||
<dl>
|
||||
{% for campaign in request.user.campaigns.all %}
|
||||
{% for campaign in campaigns %}
|
||||
<dt>Work: <a href="{% url work work_id=campaign.work.id %}">{{campaign.work.title }}</a></dt>
|
||||
<dd>
|
||||
<div class="work_campaigns clearfix">
|
||||
<div class="campaign_info">
|
||||
Campaign: {{ campaign.name }}<br />
|
||||
Campaign status: {{ campaign.status }} <br />
|
||||
Created: {{ campaign.created }}
|
||||
</div>
|
||||
<div>
|
||||
<a href="{% url manage_campaign campaign.id %}" class="manage">Manage This Campaign</a>
|
||||
Created: {{ campaign.created }}<br />
|
||||
${{ campaign.current_total }} pledged of ${{ campaign.target }}, {{ campaign.supporters_count }} supporters
|
||||
</div>
|
||||
{% if campaign.status = 'ACTIVE' or campaign.status = 'INITIALIZED' %}
|
||||
<div>
|
||||
<a href="{% url manage_campaign campaign.id %}" class="manage">Manage This Campaign</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if campaign.clone_form %}
|
||||
<div>
|
||||
<form method="POST" action="#">
|
||||
{% csrf_token %}
|
||||
{{ campaign.clone_form }}{{ campaign.clone_form.errors }}
|
||||
<input type="submit" name="clone" value="Clone this Campaign">
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</dd>
|
||||
{% endfor %}
|
||||
|
@ -51,7 +63,7 @@ Any questions not covered here? Please email us at <a href="mailto:rights@gluej
|
|||
<br />Date of Claim : {{ claim.created }}
|
||||
<br />Status of Claim: {{ claim.get_status_display }}
|
||||
{% if claim.can_open_new %}
|
||||
<h3>Open a campaign for this work</h3>
|
||||
<h3>Open a blank campaign for this work</h3>
|
||||
<form method="POST" action="#">
|
||||
{% csrf_token %}
|
||||
<p>Name the Campaign: {{ claim.campaign_form.name }}{{ claim.campaign_form.name.errors }}</p>
|
||||
|
@ -67,20 +79,30 @@ Any questions not covered here? Please email us at <a href="mailto:rights@gluej
|
|||
<h3>Campaigns for this work</h3>
|
||||
{% for campaign in claim.campaigns %}
|
||||
<div class="work_campaigns clearfix">
|
||||
<div class="campaign_info">
|
||||
Name: Your campaign, "{{ campaign.name }}", is {{ campaign.status }}<br />
|
||||
Created: {{ campaign.created }}<br />
|
||||
Manager(s): {% for user in campaign.managers.all %} <a href="{% url supporter user.username %}">{{ user.username }} </a> {% endfor %}
|
||||
<form method="POST" action="#">{% csrf_token %}
|
||||
Add/Remove Managers: {{ campaign.edit_managers_form.managers }}{{ campaign.edit_managers_form.managers.errors }}
|
||||
<input type="submit" name="edit_managers_{{campaign.id}}" value="Save Managers">
|
||||
</form>
|
||||
</div>
|
||||
{% if request.user in campaign.managers.all %}
|
||||
<div>
|
||||
<a href="{% url manage_campaign campaign.id %}" class="manage">Manage This Campaign</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if campaign.status = 'ACTIVE' or campaign.status = 'INITIALIZED' %}
|
||||
<div class="campaign_info">
|
||||
Name: Your campaign, "{{ campaign.name }}", is {{ campaign.status }}<br />
|
||||
Created: {{ campaign.created }}<br />
|
||||
Manager(s): {% for user in campaign.managers.all %} <a href="{% url supporter user.username %}">{{ user.username }} </a> {% endfor %}
|
||||
<form method="POST" action="#">{% csrf_token %}
|
||||
Add/Remove Managers: {{ campaign.edit_managers_form.managers }}{{ campaign.edit_managers_form.managers.errors }}
|
||||
<input type="submit" name="edit_managers_{{campaign.id}}" value="Save Managers">
|
||||
</form>
|
||||
</div>
|
||||
{% if request.user in campaign.managers.all %}
|
||||
<div>
|
||||
<a href="{% url manage_campaign campaign.id %}" class="manage">Manage This Campaign</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="campaign_info">
|
||||
Name: Your campaign, "{{ campaign.name }}", is {{ campaign.status }}<br />
|
||||
Created: {{ campaign.created }}<br />
|
||||
Manager(s): {% for user in campaign.managers.all %} <a href="{% url supporter user.username %}">{{ user.username }} </a> {% endfor %}
|
||||
<br />
|
||||
${{ campaign.current_total }} pledged of ${{ campaign.target }}, {{ campaign.supporters_count }} supporters
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
@ -138,20 +160,19 @@ Any questions not covered here? Please email us at <a href="mailto:rights@gluej
|
|||
</li>
|
||||
</ol>
|
||||
|
||||
<h2>Rightsholder social media tools</h2>
|
||||
|
||||
Needs to be written. What would you find helpful in a social media toolkit? <a href="/feedback">Send us feedback.</a>
|
||||
|
||||
<h2>Rewards</h2>
|
||||
|
||||
<p>Campaigns have rewards as a way to thank supporters. unglue.it includes a standard set of rewards in all campaigns. You are encouraged to add additional sweeteners to motivate people to contribute.</p>
|
||||
<p>Campaigns can have rewards as a way to motivate and thank supporters. You are strongly encouraged to add rewards - they are given special prominence on the campaign page.</p>
|
||||
|
||||
<p>Here are the standard rewards:</p>
|
||||
<p>What should you add as rewards? Anything you think you can reasonably deliver that will get supporters excited about the book. For example: other books, whether electronic or physical; artwork or multimedia relating to the book, its author, or its themes; in-person or online chats with the author; memorabilia.</p>
|
||||
|
||||
<h2>Acknowledgements</h2>
|
||||
<p>Here are the standard acknowledgements. These automatically combine with your rewards. For example, if you offer a $30 reward, ungluers who pledge $30 will receive the $25 acknowledgement as well.</p>
|
||||
<ul class="terms">
|
||||
<li><em>Any level ($1 minimum)</em> — The unglued ebook delivered to your inbox</li>
|
||||
<li><em>$25</em> — Your username under "supporters" in the acknowledgements section</li>
|
||||
<li><em>$50</em> — Your name & profile link under "benefactors"</li>
|
||||
<li><em>$100</em> — Your name, profile link, & profile tagline under "bibliophiles"</li>
|
||||
<li><em>Any amount</em> — The unglued ebook</li>
|
||||
<li><em>$25 and above</em> — Their name in the acknowledgements section under "supporters"</li>
|
||||
<li><em>$50 and above</em> — Their name & profile link under "benefactors"</li>
|
||||
<li><em>$100 and above</em> — Their name, profile link, & a dedication under "bibliophiles"</li>
|
||||
</ul>
|
||||
|
||||
<h2>More Questions</h2>
|
||||
|
|
|
@ -48,7 +48,7 @@ from regluit.frontend.forms import UserData, UserEmail, ProfileForm, CampaignPle
|
|||
from regluit.frontend.forms import RightsHolderForm, UserClaimForm, LibraryThingForm, OpenCampaignForm
|
||||
from regluit.frontend.forms import getManageCampaignForm, DonateForm, CampaignAdminForm, EmailShareForm, FeedbackForm
|
||||
from regluit.frontend.forms import EbookForm, CustomPremiumForm, EditManagersForm, EditionForm, PledgeCancelForm
|
||||
from regluit.frontend.forms import getTransferCreditForm, CCForm
|
||||
from regluit.frontend.forms import getTransferCreditForm, CCForm, CloneCampaignForm
|
||||
from regluit.payment.manager import PaymentManager
|
||||
from regluit.payment.models import Transaction, Account
|
||||
from regluit.payment.parameters import TRANSACTION_STATUS_ACTIVE, TRANSACTION_STATUS_COMPLETE, TRANSACTION_STATUS_CANCELED, TRANSACTION_STATUS_ERROR, TRANSACTION_STATUS_FAILED, TRANSACTION_STATUS_INCOMPLETE, TRANSACTION_STATUS_NONE, TRANSACTION_STATUS_MODIFIED
|
||||
|
@ -1154,7 +1154,7 @@ def rh_tools(request):
|
|||
claim.campaigns = claim.work.campaigns.all()
|
||||
else:
|
||||
claim.campaigns = []
|
||||
claim.can_open_new=True
|
||||
claim.can_open_new=False if claim.work.last_campaign_status in ['ACTIVE','INITIALIZED'] else True
|
||||
for campaign in claim.campaigns:
|
||||
if campaign.status in ['ACTIVE','INITIALIZED']:
|
||||
claim.can_open_new=False
|
||||
|
@ -1179,7 +1179,17 @@ def rh_tools(request):
|
|||
claim.campaign_form = OpenCampaignForm(data={'work': claim.work, 'name': claim.work.title, 'userid': request.user.id, 'managers_1': request.user.id})
|
||||
else:
|
||||
claim.can_open_new=False
|
||||
return render(request, "rh_tools.html", {'claims': claims ,})
|
||||
campaigns = request.user.campaigns.all()
|
||||
new_campaign = None
|
||||
for campaign in campaigns:
|
||||
if campaign.clonable():
|
||||
if request.method == 'POST' and request.POST.has_key('c%s-campaign_id'% campaign.id):
|
||||
clone_form= CloneCampaignForm(data=request.POST, prefix = 'c%s' % campaign.id)
|
||||
if clone_form.is_valid():
|
||||
campaign.clone()
|
||||
else:
|
||||
campaign.clone_form= CloneCampaignForm(initial={'campaign_id':campaign.id}, prefix = 'c%s' % campaign.id)
|
||||
return render(request, "rh_tools.html", {'claims': claims ,'campaigns': campaigns})
|
||||
|
||||
def rh_admin(request):
|
||||
if not request.user.is_authenticated() :
|
||||
|
|
Loading…
Reference in New Issue