add in credi processing; overhaul the PledgeView forms and partition authorize fn in Manager
also removed unused target, lists, ack-link,pull/1/head
parent
f299d9ecf7
commit
94270f33c6
|
@ -0,0 +1,250 @@
|
|||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'Badge'
|
||||
# first drop tables created by syncdb
|
||||
db.create_table('core_badge', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=72, blank=True)),
|
||||
('description', self.gf('django.db.models.fields.TextField')(default='', null=True)),
|
||||
))
|
||||
db.send_create_signal('core', ['Badge'])
|
||||
|
||||
# Adding M2M table for field badges on 'UserProfile'
|
||||
db.create_table('core_userprofile_badges', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('userprofile', models.ForeignKey(orm['core.userprofile'], null=False)),
|
||||
('badge', models.ForeignKey(orm['core.badge'], null=False))
|
||||
))
|
||||
db.create_unique('core_userprofile_badges', ['userprofile_id', 'badge_id'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'Badge'
|
||||
db.delete_table('core_badge')
|
||||
|
||||
# Removing M2M table for field badges on 'UserProfile'
|
||||
db.delete_table('core_userprofile_badges')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 8, 31, 2, 9, 51, 31703)'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 8, 31, 2, 9, 51, 31561)'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'core.author': {
|
||||
'Meta': {'object_name': 'Author'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'editions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Edition']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '500'})
|
||||
},
|
||||
'core.badge': {
|
||||
'Meta': {'object_name': 'Badge'},
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '72', 'blank': 'True'})
|
||||
},
|
||||
'core.campaign': {
|
||||
'Meta': {'object_name': 'Campaign'},
|
||||
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'deadline': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'description': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
|
||||
'details': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'null': 'True', 'to': "orm['core.Edition']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'license': ('django.db.models.fields.CharField', [], {'default': "'CC BY-NC-ND'", 'max_length': '255'}),
|
||||
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
|
||||
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True'}),
|
||||
'target': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.campaignaction': {
|
||||
'Meta': {'object_name': 'CampaignAction'},
|
||||
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'to': "orm['core.Campaign']"}),
|
||||
'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '15'})
|
||||
},
|
||||
'core.celerytask': {
|
||||
'Meta': {'object_name': 'CeleryTask'},
|
||||
'active': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 8, 31, 2, 9, 50, 804173)', 'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True'}),
|
||||
'function_args': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||
'function_name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'task_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'null': 'True', 'to': "orm['auth.User']"})
|
||||
},
|
||||
'core.claim': {
|
||||
'Meta': {'object_name': 'Claim'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'rights_holder': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.RightsHolder']"}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '7'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['auth.User']"}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.ebook': {
|
||||
'Meta': {'object_name': 'Ebook'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebooks'", 'to': "orm['core.Edition']"}),
|
||||
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'rights': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'unglued': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
|
||||
},
|
||||
'core.edition': {
|
||||
'Meta': {'object_name': 'Edition'},
|
||||
'cover_image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
|
||||
'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.identifier': {
|
||||
'Meta': {'unique_together': "(('type', 'value'),)", 'object_name': 'Identifier'},
|
||||
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'null': 'True', 'to': "orm['core.Edition']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '31'}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.key': {
|
||||
'Meta': {'object_name': 'Key'},
|
||||
'encrypted_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
|
||||
},
|
||||
'core.premium': {
|
||||
'Meta': {'object_name': 'Premium'},
|
||||
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
|
||||
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'limit': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
|
||||
},
|
||||
'core.rightsholder': {
|
||||
'Meta': {'object_name': 'RightsHolder'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rights_holder'", 'to': "orm['auth.User']"}),
|
||||
'rights_holder_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'core.subject': {
|
||||
'Meta': {'ordering': "['name']", 'object_name': 'Subject'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'}),
|
||||
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.userprofile': {
|
||||
'Meta': {'object_name': 'UserProfile'},
|
||||
'badges': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'holders'", 'symmetrical': 'False', 'to': "orm['core.Badge']"}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'facebook_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
|
||||
'goodreads_auth_secret': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'goodreads_auth_token': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'goodreads_user_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
|
||||
'goodreads_user_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
|
||||
'goodreads_user_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
|
||||
'home_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '31', 'blank': 'True'}),
|
||||
'pic_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
|
||||
'tagline': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
|
||||
'twitter_id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
|
||||
},
|
||||
'core.waswork': {
|
||||
'Meta': {'object_name': 'WasWork'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'moved': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
|
||||
'was': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.wishes': {
|
||||
'Meta': {'object_name': 'Wishes', 'db_table': "'core_wishlist_works'"},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'source': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
|
||||
'wishlist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']"}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wishes'", 'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.wishlist': {
|
||||
'Meta': {'object_name': 'Wishlist'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}),
|
||||
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'through': "orm['core.Wishes']", 'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.work': {
|
||||
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
|
||||
'num_wishes': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['core']
|
|
@ -296,16 +296,15 @@ class CampaignPledgeForm(forms.Form):
|
|||
)
|
||||
anonymous = forms.BooleanField(required=False, label=_("Don't display my name in the acknowledgements"))
|
||||
ack_name = forms.CharField(required=False, max_length=64, label=_("What name should we display?"))
|
||||
ack_link = forms.URLField(required=False, label=_("Your web site:"))
|
||||
ack_dedication = forms.CharField(required=False, max_length=140, label=_("Your dedication:"))
|
||||
|
||||
premium_id = forms.IntegerField(required=False)
|
||||
|
||||
def clean_preapproval_amount(self):
|
||||
data = self.cleaned_data['preapproval_amount']
|
||||
if data is None:
|
||||
preapproval_amount = self.cleaned_data['preapproval_amount']
|
||||
if preapproval_amount is None:
|
||||
raise forms.ValidationError(_("Please enter a pledge amount."))
|
||||
return data
|
||||
return preapproval_amount
|
||||
|
||||
# should we do validation on the premium_id here?
|
||||
# can see whether it corresponds to a real premium -- do that here?
|
||||
|
@ -317,11 +316,6 @@ class CampaignPledgeForm(forms.Form):
|
|||
try:
|
||||
preapproval_amount = cleaned_data.get("preapproval_amount")
|
||||
premium_id = int(cleaned_data.get("premium_id"))
|
||||
premium_amount = Premium.objects.get(id=premium_id).amount
|
||||
logger.info("preapproval_amount: {0}, premium_id: {1}, premium_amount:{2}".format(preapproval_amount, premium_id, premium_amount))
|
||||
if preapproval_amount < premium_amount:
|
||||
logger.info("raising form validating error")
|
||||
raise forms.ValidationError(_("Sorry, you must pledge at least $%s to select that premium." % (premium_amount)))
|
||||
try:
|
||||
premium= Premium.objects.get(id=premium_id)
|
||||
if premium.limit>0:
|
||||
|
@ -329,6 +323,11 @@ class CampaignPledgeForm(forms.Form):
|
|||
raise forms.ValidationError(_("Sorry, that premium is fully subscribed."))
|
||||
except Premium.DoesNotExist:
|
||||
raise forms.ValidationError(_("Sorry, that premium is not valid."))
|
||||
premium_amount = premium.amount
|
||||
logger.info("preapproval_amount: {0}, premium_id: {1}, premium_amount:{2}".format(preapproval_amount, premium_id, premium_amount))
|
||||
if preapproval_amount < premium_amount:
|
||||
logger.info("raising form validating error")
|
||||
raise forms.ValidationError(_("Sorry, you must pledge at least $%s to select that premium." % (premium_amount)))
|
||||
|
||||
except Exception, e:
|
||||
if isinstance(e, forms.ValidationError):
|
||||
|
|
|
@ -108,6 +108,8 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cancel_notice">
|
||||
{% if faqmenu == 'modify' %}We hope you won't, but of course you're also free to <a href="{% url pledge_cancel campaign_id=work.last_campaign.id %}">cancel your pledge</a>.{% endif %}</div>
|
||||
<div id="pass_supporter_name" style="display: none;">{{ request.user.username }}</div>
|
||||
{% if transaction.ack_name %}
|
||||
<div id="pass_ack_name" style="display: none;">{{ transaction.ack_name }}</div>
|
||||
|
|
|
@ -7,7 +7,7 @@ from django.conf import settings
|
|||
|
||||
from regluit.core.feeds import SupporterWishlistFeed
|
||||
from regluit.core.models import Campaign
|
||||
from regluit.frontend.views import GoodreadsDisplayView, LibraryThingView, PledgeView, PledgeCompleteView, PledgeModifyView, PledgeCancelView, PledgeNeverMindView, PledgeRechargeView, FAQView
|
||||
from regluit.frontend.views import GoodreadsDisplayView, LibraryThingView, PledgeView, PledgeCompleteView, PledgeCancelView, PledgeRechargeView, FAQView
|
||||
from regluit.frontend.views import CampaignListView, DonateView, WorkListView, UngluedListView, InfoPageView, InfoLangView, DonationView
|
||||
|
||||
urlpatterns = patterns(
|
||||
|
@ -55,8 +55,7 @@ urlpatterns = patterns(
|
|||
url(r"^pledge/(?P<work_id>\d+)/$", login_required(PledgeView.as_view()), name="pledge"),
|
||||
url(r"^pledge/cancel/(?P<campaign_id>\d+)$", login_required(PledgeCancelView.as_view()), name="pledge_cancel"),
|
||||
url(r"^pledge/complete/$", login_required(PledgeCompleteView.as_view()), name="pledge_complete"),
|
||||
url(r"^pledge/nevermind/$", login_required(PledgeNeverMindView.as_view()), name="pledge_nevermind"),
|
||||
url(r"^pledge/modify/(?P<work_id>\d+)$", login_required(PledgeModifyView.as_view()), name="pledge_modify"),
|
||||
url(r"^pledge/modify/(?P<work_id>\d+)$", login_required(PledgeView.as_view()), name="pledge_modify"),
|
||||
url(r"^pledge/recharge/(?P<work_id>\d+)$", login_required(PledgeRechargeView.as_view()), name="pledge_recharge"),
|
||||
url(r"^subjects/$", "subjects", name="subjects"),
|
||||
url(r"^librarything/$", LibraryThingView.as_view(), name="librarything"),
|
||||
|
|
|
@ -50,8 +50,8 @@ from regluit.frontend.forms import EbookForm, CustomPremiumForm, EditManagersFor
|
|||
from regluit.frontend.forms import getTransferCreditForm
|
||||
from regluit.payment.manager import PaymentManager
|
||||
from regluit.payment.models import Transaction
|
||||
from regluit.payment.parameters import TARGET_TYPE_CAMPAIGN, TARGET_TYPE_DONATION, PAYMENT_TYPE_AUTHORIZATION
|
||||
from regluit.payment.parameters import TRANSACTION_STATUS_ACTIVE, TRANSACTION_STATUS_COMPLETE, TRANSACTION_STATUS_CANCELED, TRANSACTION_STATUS_ERROR, TRANSACTION_STATUS_FAILED, TRANSACTION_STATUS_INCOMPLETE
|
||||
from regluit.payment.parameters import PAYMENT_TYPE_AUTHORIZATION
|
||||
from regluit.core import goodreads
|
||||
from tastypie.models import ApiKey
|
||||
from regluit.payment.models import Transaction
|
||||
|
@ -583,280 +583,142 @@ class DonationView(TemplateView):
|
|||
class PledgeView(FormView):
|
||||
template_name="pledge.html"
|
||||
form_class = CampaignPledgeForm
|
||||
transaction = None
|
||||
campaign = None
|
||||
work = None
|
||||
premiums = None
|
||||
data = None
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
# change the default behavior from https://code.djangoproject.com/browser/django/tags/releases/1.3.1/django/views/generic/edit.py#L129
|
||||
# don't automatically bind the data to the form on GET, only on POST
|
||||
# compare with https://code.djangoproject.com/browser/django/tags/releases/1.3.1/django/views/generic/edit.py#L34
|
||||
form_class = self.get_form_class()
|
||||
form = form_class()
|
||||
|
||||
context_data = self.get_context_data(form=form)
|
||||
# if there is already an active campaign pledge for user, redirect to the pledge modify page
|
||||
if context_data.get('redirect_to_modify_pledge'):
|
||||
work = context_data['work']
|
||||
return HttpResponseRedirect(reverse('pledge_modify', args=[work.id]))
|
||||
else:
|
||||
return self.render_to_response(context_data)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""set up the pledge page"""
|
||||
|
||||
# the following should be true since PledgeModifyView.as_view is wrapped in login_required
|
||||
def get_form_kwargs(self):
|
||||
assert self.request.user.is_authenticated()
|
||||
user = self.request.user
|
||||
|
||||
context = super(PledgeView, self).get_context_data(**kwargs)
|
||||
|
||||
work = get_object_or_404(models.Work, id=self.kwargs["work_id"])
|
||||
campaign = work.last_campaign()
|
||||
self.work = get_object_or_404(models.Work, id=self.kwargs["work_id"])
|
||||
|
||||
# if there is no campaign or if campaign is not active, we should raise an error
|
||||
|
||||
if campaign is None or campaign.status != 'ACTIVE':
|
||||
raise Http404
|
||||
|
||||
custom_premiums = campaign.custom_premiums()
|
||||
# need to also include the no-premiums default in the queryset we send the page
|
||||
premiums = custom_premiums | models.Premium.objects.filter(id=150)
|
||||
premium_id = self.request.REQUEST.get('premium_id', None)
|
||||
preapproval_amount = self.request.REQUEST.get('preapproval_amount', None)
|
||||
try:
|
||||
self.campaign = self.work.last_campaign()
|
||||
# TODO need to sort the premiums
|
||||
self.premiums = self.campaign.custom_premiums() | models.Premium.objects.filter(id=150)
|
||||
# Campaign must be ACTIVE
|
||||
assert self.campaign.status == 'ACTIVE'
|
||||
except Exception, e:
|
||||
raise e
|
||||
|
||||
transactions = self.campaign.transactions().filter(user=self.request.user, status=TRANSACTION_STATUS_ACTIVE, type=PAYMENT_TYPE_AUTHORIZATION)
|
||||
if transactions.count() == 0:
|
||||
premium_id = self.request.REQUEST.get('premium_id', None)
|
||||
preapproval_amount = self.request.REQUEST.get('preapproval_amount', None)
|
||||
premium_description = None
|
||||
ack_name=''
|
||||
ack_dedication=''
|
||||
anonymous=''
|
||||
|
||||
else:
|
||||
self.transaction = transactions[0]
|
||||
# what stuff do we need to pull out to populate form?
|
||||
# preapproval_amount, premium_id (which we don't have stored yet)
|
||||
if self.transaction.premium is not None:
|
||||
premium_id = self.transaction.premium.id
|
||||
premium_description = self.transaction.premium.description
|
||||
else:
|
||||
premium_id = None
|
||||
premium_description = None
|
||||
preapproval_amount = self.transaction.amount
|
||||
ack_name=self.transaction.ack_name
|
||||
ack_dedication=self.transaction.ack_dedication
|
||||
anonymous=self.transaction.anonymous
|
||||
|
||||
if premium_id is not None and preapproval_amount is None:
|
||||
try:
|
||||
preapproval_amount = D(models.Premium.objects.get(id=premium_id).amount)
|
||||
except:
|
||||
preapproval_amount = None
|
||||
|
||||
data = {'preapproval_amount':preapproval_amount, 'premium_id':premium_id}
|
||||
|
||||
form_class = self.get_form_class()
|
||||
|
||||
# no validation errors, please, when we're only doing a GET
|
||||
# to avoid validation errors, don't bind the form
|
||||
|
||||
if preapproval_amount is not None:
|
||||
form = form_class(data)
|
||||
self.data = {'preapproval_amount':preapproval_amount,
|
||||
'premium_id':premium_id, 'premium_description':premium_description,
|
||||
'ack_name':ack_name, 'ack_dedication':ack_dedication, 'anonymous':anonymous}
|
||||
if self.request.method == 'POST':
|
||||
self.data.update(self.request.POST.dict())
|
||||
if self.request.method == 'POST' or premium_id:
|
||||
return {'data':self.data}
|
||||
else:
|
||||
form = form_class()
|
||||
|
||||
return {}
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""set up the pledge page"""
|
||||
|
||||
context = super(PledgeView, self).get_context_data(**kwargs)
|
||||
|
||||
try:
|
||||
pubdate = work.publication_date[:4]
|
||||
pubdate = self.work.publication_date[:4]
|
||||
except IndexError:
|
||||
pubdate = 'unknown'
|
||||
|
||||
context.update({
|
||||
'redirect_to_modify_pledge':False,
|
||||
'work':work,'campaign':campaign,
|
||||
'premiums':premiums, 'form':form,
|
||||
'premium_id':premium_id,
|
||||
'faqmenu': 'pledge',
|
||||
'work':self.work,
|
||||
'campaign':self.campaign,
|
||||
'premiums':self.premiums,
|
||||
'premium_id':self.data['premium_id'],
|
||||
'faqmenu': 'modify' if self.transaction else 'pledge',
|
||||
'pubdate':pubdate,
|
||||
'payment_processor':settings.PAYMENT_PROCESSOR,
|
||||
})
|
||||
'transaction': self.transaction,
|
||||
'tid': self.transaction.id if self.transaction else None,
|
||||
'premium_description': self.data['premium_description'],
|
||||
'preapproval_amount':self.data['preapproval_amount'],
|
||||
'payment_processor':self.transaction.host if self.transaction else None,
|
||||
})
|
||||
|
||||
# check whether the user already has an ACTIVE transaction for the given campaign.
|
||||
# if so, we should redirect the user to modify pledge page
|
||||
# BUGBUG: but what about Completed Transactions?
|
||||
transactions = campaign.transactions().filter(user=user, status=TRANSACTION_STATUS_ACTIVE)
|
||||
if transactions.count() > 0:
|
||||
context.update({'redirect_to_modify_pledge':True})
|
||||
else:
|
||||
context.update({'redirect_to_modify_pledge':False})
|
||||
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
work_id = self.kwargs["work_id"]
|
||||
preapproval_amount = form.cleaned_data["preapproval_amount"]
|
||||
anonymous = form.cleaned_data["anonymous"]
|
||||
ack_name = form.cleaned_data["ack_name"]
|
||||
ack_link = form.cleaned_data["ack_link"]
|
||||
ack_dedication = form.cleaned_data["ack_dedication"]
|
||||
def get_premium(self,form):
|
||||
premium_id = form.cleaned_data["premium_id"]
|
||||
# confirm that the premium_id is a valid one for the campaign in question
|
||||
try:
|
||||
premium = models.Premium.objects.get(id=premium_id)
|
||||
if not (premium.campaign is None or premium.campaign == self.campaign):
|
||||
premium = None
|
||||
except models.Premium.DoesNotExist, e:
|
||||
premium = None
|
||||
return premium
|
||||
|
||||
def form_valid(self, form):
|
||||
# right now, if there is a non-zero pledge amount, go with that. otherwise, do the pre_approval
|
||||
campaign = models.Work.objects.get(id=int(work_id)).last_campaign()
|
||||
|
||||
premium_id = form.cleaned_data["premium_id"]
|
||||
# confirm that the premium_id is a valid one for the campaign in question
|
||||
try:
|
||||
premium = models.Premium.objects.get(id=premium_id)
|
||||
if not (premium.campaign is None or premium.campaign == campaign):
|
||||
premium = None
|
||||
except models.Premium.DoesNotExist, e:
|
||||
premium = None
|
||||
|
||||
p = PaymentManager(embedded=self.embedded)
|
||||
|
||||
# PledgeView is wrapped in login_required -- so in theory, user should never be None -- but I'll keep this logic here for now.
|
||||
if self.request.user.is_authenticated():
|
||||
user = self.request.user
|
||||
p = PaymentManager()
|
||||
if self.transaction:
|
||||
# modifying the transaction...
|
||||
assert self.transaction.type == PAYMENT_TYPE_AUTHORIZATION and self.transaction.status == TRANSACTION_STATUS_ACTIVE
|
||||
status, url = p.modify_transaction(self.transaction, form.cleaned_data["preapproval_amount"],
|
||||
premium=self.get_premium(form),
|
||||
paymentReason="Unglue.it Pledge for {0}".format(self.campaign.name),
|
||||
ack_name=form.cleaned_data["ack_name"],
|
||||
ack_dedication=form.cleaned_data["ack_dedication"],
|
||||
anonymous=form.cleaned_data["anonymous"],
|
||||
)
|
||||
logger.info("status: {0}, url:{1}".format(status, url))
|
||||
|
||||
if status and url is not None:
|
||||
logger.info("PledgeView (Modify): " + url)
|
||||
return HttpResponseRedirect(url)
|
||||
elif status and url is None:
|
||||
return HttpResponseRedirect("{0}?tid={1}".format(reverse('pledge_complete'), self.transaction.id))
|
||||
else:
|
||||
return HttpResponse("No modification made")
|
||||
else:
|
||||
user = None
|
||||
|
||||
if not self.embedded:
|
||||
|
||||
return_url = None
|
||||
nevermind_url = None
|
||||
|
||||
# the recipients of this authorization is not specified here but rather by the PaymentManager.
|
||||
# set the expiry date based on the campaign deadline
|
||||
expiry = campaign.deadline + timedelta( days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN )
|
||||
|
||||
paymentReason = "Unglue.it Pledge for {0}".format(campaign.name)
|
||||
t, url = p.authorize('USD', TARGET_TYPE_CAMPAIGN, preapproval_amount, expiry=expiry, campaign=campaign, list=None, user=user,
|
||||
return_url=return_url, nevermind_url=nevermind_url, anonymous=anonymous, premium=premium,
|
||||
paymentReason=paymentReason, ack_name=ack_name, ack_link=ack_link, ack_dedication=ack_dedication)
|
||||
else: # embedded view -- which we're not actively using right now.
|
||||
# embedded view triggerws instant payment: send to the partnering RH
|
||||
receiver_list = [{'email':settings.PAYPAL_NONPROFIT_PARTNER_EMAIL, 'amount':preapproval_amount}]
|
||||
|
||||
return_url = None
|
||||
nevermind_url = None
|
||||
|
||||
t, url = p.pledge('USD', TARGET_TYPE_CAMPAIGN, receiver_list, campaign=campaign, list=None, user=user,
|
||||
return_url=return_url, nevermind_url=nevermind_url, anonymous=anonymous, premium=premium,
|
||||
ack_name=ack_name, ack_link=ack_link, ack_dedication=ack_dedication)
|
||||
|
||||
if url:
|
||||
logger.info("PledgeView url: " + url)
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
logger.error("Attempt to produce transaction id {0} failed".format(t.id))
|
||||
return HttpResponse("Our attempt to enable your transaction failed. We have logged this error.")
|
||||
|
||||
class PledgeModifyView(FormView):
|
||||
"""
|
||||
A view to handle request to change an existing pledge
|
||||
"""
|
||||
|
||||
template_name="pledge.html"
|
||||
form_class = CampaignPledgeForm
|
||||
embedded = False
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
context = super(PledgeModifyView, self).get_context_data(**kwargs)
|
||||
|
||||
# the following should be true since PledgeModifyView.as_view is wrapped in login_required
|
||||
assert self.request.user.is_authenticated()
|
||||
user = self.request.user
|
||||
|
||||
work = get_object_or_404(models.Work, id=self.kwargs["work_id"])
|
||||
|
||||
try:
|
||||
campaign = work.last_campaign()
|
||||
premiums = campaign.custom_premiums() | models.Premium.objects.filter(id=150)
|
||||
|
||||
# which combination of campaign and transaction status required?
|
||||
# Campaign must be ACTIVE
|
||||
assert campaign.status == 'ACTIVE'
|
||||
|
||||
transactions = campaign.transactions().filter(user=user, status=TRANSACTION_STATUS_ACTIVE)
|
||||
assert transactions.count() == 1
|
||||
transaction = transactions[0]
|
||||
assert transaction.type == PAYMENT_TYPE_AUTHORIZATION and transaction.status == TRANSACTION_STATUS_ACTIVE
|
||||
|
||||
except Exception, e:
|
||||
raise e
|
||||
|
||||
# what stuff do we need to pull out to populate form?
|
||||
# preapproval_amount, premium_id (which we don't have stored yet)
|
||||
if transaction.premium is not None:
|
||||
premium_id = transaction.premium.id
|
||||
premium_description = transaction.premium.description
|
||||
else:
|
||||
premium_id = None
|
||||
premium_description = None
|
||||
|
||||
# is there a Transaction for an ACTIVE campaign for this
|
||||
# should make sure Transaction is modifiable.
|
||||
|
||||
preapproval_amount = transaction.amount
|
||||
data = {'preapproval_amount':preapproval_amount, 'premium_id':premium_id}
|
||||
|
||||
# initialize form with the current state of the transaction if the current values empty
|
||||
form = kwargs['form']
|
||||
|
||||
if not(form.is_bound):
|
||||
form_class = self.get_form_class()
|
||||
form = form_class(initial=data)
|
||||
|
||||
context.update({
|
||||
'work':work,
|
||||
'campaign':campaign,
|
||||
'premiums':premiums,
|
||||
'form':form,
|
||||
'preapproval_amount':preapproval_amount,
|
||||
'premium_id':premium_id,
|
||||
'premium_description': premium_description,
|
||||
'faqmenu': 'modify',
|
||||
'tid': transaction.id,
|
||||
'payment_processor':settings.PAYMENT_PROCESSOR,
|
||||
'transaction': transaction,
|
||||
})
|
||||
return context
|
||||
|
||||
|
||||
def form_invalid(self, form):
|
||||
logger.info("form.non_field_errors: {0}".format(form.non_field_errors()))
|
||||
response = self.render_to_response(self.get_context_data(form=form))
|
||||
return response
|
||||
|
||||
def form_valid(self, form):
|
||||
|
||||
# What are the situations we need to deal with?
|
||||
# 2 main situations: if the new amount is less than max_amount, no need to go out to PayPal again
|
||||
# if new amount is greater than max_amount...need to go out and get new approval.
|
||||
# to start with, we can use the standard pledge_complete, pledge_cancel machinery
|
||||
# might have to modify the pledge_complete, pledge_cancel because the messages are going to be
|
||||
# different because we're modifying a pledge rather than a new one.
|
||||
|
||||
work_id = self.kwargs["work_id"]
|
||||
preapproval_amount = form.cleaned_data["preapproval_amount"]
|
||||
ack_name = form.cleaned_data["ack_name"]
|
||||
ack_link = form.cleaned_data["ack_link"]
|
||||
ack_dedication = form.cleaned_data["ack_dedication"]
|
||||
anonymous = form.cleaned_data["anonymous"]
|
||||
|
||||
assert self.request.user.is_authenticated()
|
||||
user = self.request.user
|
||||
|
||||
# right now, if there is a non-zero pledge amount, go with that. otherwise, do the pre_approval
|
||||
campaign = models.Work.objects.get(id=int(work_id)).last_campaign()
|
||||
assert campaign.status == 'ACTIVE'
|
||||
|
||||
premium_id = form.cleaned_data["premium_id"]
|
||||
# confirm that the premium_id is a valid one for the campaign in question
|
||||
try:
|
||||
premium = models.Premium.objects.get(id=premium_id)
|
||||
if not (premium.campaign is None or premium.campaign == campaign):
|
||||
premium = None
|
||||
except models.Premium.DoesNotExist, e:
|
||||
premium = None
|
||||
|
||||
transactions = campaign.transactions().filter(user=user, status=TRANSACTION_STATUS_ACTIVE)
|
||||
assert transactions.count() == 1
|
||||
transaction = transactions[0]
|
||||
assert transaction.type == PAYMENT_TYPE_AUTHORIZATION and transaction.status == TRANSACTION_STATUS_ACTIVE
|
||||
|
||||
p = PaymentManager(embedded=self.embedded)
|
||||
paymentReason = "Unglue.it Pledge for {0}".format(campaign.name)
|
||||
status, url = p.modify_transaction(transaction=transaction, amount=preapproval_amount, premium=premium,
|
||||
paymentReason=paymentReason, ack_name=ack_name, ack_link=ack_link,
|
||||
ack_dedication=ack_dedication, anonymous=anonymous)
|
||||
|
||||
logger.info("status: {0}, url:{1}".format(status, url))
|
||||
|
||||
if status and url is not None:
|
||||
logger.info("PledgeModifyView paypal: " + url)
|
||||
return HttpResponseRedirect(url)
|
||||
elif status and url is None:
|
||||
# let's use the pledge_complete template for now and maybe look into customizing it.
|
||||
return HttpResponseRedirect("{0}?tid={1}".format(reverse('pledge_complete'), transaction.id))
|
||||
else:
|
||||
return HttpResponse("No modification made")
|
||||
|
||||
t, url = p.process_transaction('USD', form.cleaned_data["preapproval_amount"],
|
||||
host = None,
|
||||
campaign=self.campaign,
|
||||
user=self.request.user,
|
||||
premium=premium,
|
||||
paymentReason="Unglue.it Pledge for {0}".format(self.campaign.name),
|
||||
ack_name=form.cleaned_data["ack_name"],
|
||||
ack_dedication=form.cleaned_data["ack_dedication"],
|
||||
anonymous=form.cleaned_data["anonymous"],
|
||||
)
|
||||
if url:
|
||||
logger.info("PledgeView url: " + url)
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
logger.error("Attempt to produce transaction id {0} failed".format(t.id))
|
||||
return HttpResponse("Our attempt to enable your transaction failed. We have logged this error.")
|
||||
|
||||
|
||||
class PledgeRechargeView(TemplateView):
|
||||
|
@ -869,7 +731,7 @@ class PledgeRechargeView(TemplateView):
|
|||
|
||||
context = super(PledgeRechargeView, self).get_context_data(**kwargs)
|
||||
|
||||
# the following should be true since PledgeModifyView.as_view is wrapped in login_required
|
||||
# the following should be true since PledgeView.as_view is wrapped in login_required
|
||||
assert self.request.user.is_authenticated()
|
||||
user = self.request.user
|
||||
|
||||
|
@ -888,18 +750,15 @@ class PledgeRechargeView(TemplateView):
|
|||
|
||||
if transaction is not None:
|
||||
# the recipients of this authorization is not specified here but rather by the PaymentManager.
|
||||
# set the expiry date based on the campaign deadline
|
||||
expiry = campaign.deadline + timedelta( days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN )
|
||||
ack_name = transaction.ack_name
|
||||
ack_link = transaction.ack_link
|
||||
ack_dedication = transaction.ack_dedication
|
||||
|
||||
paymentReason = "Unglue.it Recharge for {0}".format(campaign.name)
|
||||
|
||||
p = PaymentManager(embedded=False)
|
||||
t, url = p.authorize('USD', TARGET_TYPE_CAMPAIGN, transaction.amount, expiry=expiry, campaign=campaign, list=None, user=user,
|
||||
return_url=return_url, nevermind_url=nevermind_url, anonymous=transaction.anonymous, premium=transaction.premium,
|
||||
paymentReason=paymentReason, ack_name=ack_name, ack_link=ack_link, ack_dedication=ack_dedication)
|
||||
p = PaymentManager()
|
||||
t, url = p.authorize('USD', transaction.amount, campaign=campaign, list=None, user=user,
|
||||
return_url=return_url, anonymous=transaction.anonymous, premium=transaction.premium,
|
||||
paymentReason=paymentReason, ack_name=ack_name, ack_dedication=ack_dedication)
|
||||
logger.info("Recharge url: {0}".format(url))
|
||||
else:
|
||||
url = None
|
||||
|
@ -1090,73 +949,11 @@ class PledgeCancelView(FormView):
|
|||
except Exception, e:
|
||||
logger.error("Exception from attempt to cancel pledge for campaign id {0} for username {1}: {2}".format(campaign_id, user.username, e))
|
||||
return HttpResponse("Sorry, something went wrong in canceling your campaign pledge. We have logged this error.")
|
||||
|
||||
|
||||
class PledgeNeverMindView(TemplateView):
|
||||
"""A callback for PayPal to tell unglue.it that a payment transaction has been canceled by the user"""
|
||||
template_name="pledge_nevermind.html"
|
||||
|
||||
def get_context_data(self):
|
||||
context = super(PledgeNeverMindView, self).get_context_data()
|
||||
|
||||
if self.request.user.is_authenticated():
|
||||
user = self.request.user
|
||||
else:
|
||||
user = None
|
||||
|
||||
# pull out the transaction id and try to get the corresponding Transaction
|
||||
transaction_id = self.request.REQUEST.get("tid")
|
||||
transaction = Transaction.objects.get(id=transaction_id)
|
||||
|
||||
# work and campaign in question
|
||||
try:
|
||||
campaign = transaction.campaign
|
||||
work = campaign.work
|
||||
except Exception, e:
|
||||
campaign = None
|
||||
work = None
|
||||
|
||||
# we need to check whether the user tied to the transaction is indeed the authenticated user.
|
||||
|
||||
correct_user = False
|
||||
try:
|
||||
if user.id == transaction.user.id:
|
||||
correct_user = True
|
||||
except Exception, e:
|
||||
pass
|
||||
|
||||
# check that the user had not already approved the transaction
|
||||
# do we need to first run PreapprovalDetails to check on the status
|
||||
|
||||
# is it of type=PAYMENT_TYPE_AUTHORIZATION and status is NONE or ACTIVE (but approved is false)
|
||||
|
||||
if transaction.type == PAYMENT_TYPE_AUTHORIZATION:
|
||||
correct_transaction_type = True
|
||||
else:
|
||||
correct_transaction_type = False
|
||||
|
||||
# status?
|
||||
|
||||
# give the user an opportunity to approved the transaction again
|
||||
# provide a URL to click on.
|
||||
# https://www.sandbox.paypal.com/?cmd=_ap-preapproval&preapprovalkey=PA-6JV656290V840615H
|
||||
try_again_url = '%s?cmd=_ap-preapproval&preapprovalkey=%s' % (settings.PAYPAL_PAYMENT_HOST, transaction.preapproval_key)
|
||||
|
||||
context["transaction"] = transaction
|
||||
context["correct_user"] = correct_user
|
||||
context["correct_transaction_type"] = correct_transaction_type
|
||||
context["try_again_url"] = try_again_url
|
||||
context["work"] = work
|
||||
context["campaign"] = campaign
|
||||
context["faqmenu"] = "cancel"
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class DonateView(FormView):
|
||||
template_name="donate.html"
|
||||
form_class = DonateForm
|
||||
embedded = False
|
||||
|
||||
#def get_context_data(self, **kwargs):
|
||||
# context = super(DonateView, self).get_context_data(**kwargs)
|
||||
|
@ -1173,7 +970,7 @@ class DonateView(FormView):
|
|||
# right now, if there is a non-zero pledge amount, go with that. otherwise, do the pre_approval
|
||||
campaign = None
|
||||
|
||||
p = PaymentManager(embedded=self.embedded)
|
||||
p = PaymentManager()
|
||||
|
||||
# we should force login at this point -- or if no account, account creation, login, and return to this spot
|
||||
if self.request.user.is_authenticated():
|
||||
|
@ -1187,8 +984,8 @@ class DonateView(FormView):
|
|||
#redirect the page back to campaign page on success
|
||||
return_url = self.request.build_absolute_uri(reverse('donate'))
|
||||
|
||||
t, url = p.pledge('USD', TARGET_TYPE_DONATION, receiver_list, campaign=campaign, list=None, user=user,
|
||||
return_url=return_url, anonymous=anonymous, ack_name=ack_name, ack_link=ack_link,
|
||||
t, url = p.pledge('USD', receiver_list, campaign=campaign, list=None, user=user,
|
||||
return_url=return_url, anonymous=anonymous, ack_name=ack_name,
|
||||
ack_dedication=ack_dedication)
|
||||
|
||||
if url:
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
from datetime import timedelta
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.conf import settings
|
||||
|
||||
from regluit.payment.parameters import *
|
||||
from regluit.utils.localdatetime import now
|
||||
from regluit.payment.baseprocessor import BasePaymentRequest
|
||||
|
||||
|
||||
def pledge_transaction(t,user,amount):
|
||||
"""commit <amount> from a <user>'s credit to a specified transaction <t>"""
|
||||
|
||||
if t.amount and t.host == PAYMENT_HOST_CREDIT:
|
||||
#changing the pledge_transaction
|
||||
user.credit.add_to_pledged(amount-t.amount)
|
||||
else:
|
||||
user.credit.add_to_pledged(amount)
|
||||
t.amount=amount
|
||||
t.max_amount=amount
|
||||
t.host = PAYMENT_HOST_CREDIT
|
||||
t.type = PAYMENT_TYPE_AUTHORIZATION
|
||||
t.status=TRANSACTION_STATUS_ACTIVE
|
||||
t.approved=True
|
||||
now_val = now()
|
||||
t.date_authorized = now_val
|
||||
t.date_expired = now_val + timedelta( days=settings.PREAPPROVAL_PERIOD )
|
||||
|
||||
t.save()
|
||||
|
||||
|
||||
class CancelPreapproval(BasePaymentRequest):
|
||||
'''
|
||||
Cancels an exisiting token.
|
||||
'''
|
||||
|
||||
def __init__(self, transaction):
|
||||
self.transaction = transaction
|
||||
if transaction.user.credit.add_to_pledged(-transaction.amount):
|
||||
#success
|
||||
transaction.status=TRANSACTION_STATUS_CANCELED
|
||||
transaction.save()
|
||||
else:
|
||||
self.errorMessage="couldn't cancel the transaction"
|
||||
self.status = 'Credit Cancel Failure'
|
||||
|
||||
class PreapprovalDetails(BasePaymentRequest):
|
||||
status = None
|
||||
approved = None
|
||||
currency = None
|
||||
amount = None
|
||||
def __init__(self, transaction):
|
||||
self.status = transaction.status
|
||||
self.approved = transaction.approved
|
||||
self.currency = transaction.currency
|
||||
self.amount = transaction.amount
|
|
@ -5,6 +5,9 @@ from django.core.urlresolvers import reverse
|
|||
from django.conf import settings
|
||||
from regluit.payment.parameters import *
|
||||
from regluit.payment.signals import transaction_charged, pledge_modified, pledge_created
|
||||
from regluit.payment import credit
|
||||
|
||||
from regluit.payment.baseprocessor import Pay, Finish, Preapproval, ProcessIPN, CancelPreapproval, PaymentDetails, PreapprovalDetails, RefundPayment
|
||||
|
||||
import uuid
|
||||
import traceback
|
||||
|
@ -14,6 +17,8 @@ import logging
|
|||
from decimal import Decimal as D
|
||||
from xml.dom import minidom
|
||||
import urllib, urlparse
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -531,58 +536,28 @@ class PaymentManager( object ):
|
|||
logger.info("Cancel Transaction " + str(transaction.id) + " Failed with error: " + p.error_string())
|
||||
return False
|
||||
|
||||
def authorize(self, currency, target, amount, expiry=None, campaign=None, list=None, user=None,
|
||||
return_url=None, nevermind_url=None, anonymous=False, premium=None,
|
||||
paymentReason="unglue.it Pledge", ack_name=None, ack_link=None, ack_dedication=None,
|
||||
modification=False):
|
||||
def authorize(self, transaction, expiry= None, return_url=None, paymentReason="unglue.it Pledge", modification=False):
|
||||
'''
|
||||
authorize
|
||||
|
||||
authorizes a set amount of money to be collected at a later date
|
||||
|
||||
currency: a 3-letter paypal currency code, i.e. USD
|
||||
target: a defined target type, i.e. TARGET_TYPE_CAMPAIGN, TARGET_TYPE_LIST, TARGET_TYPE_NONE
|
||||
amount: the amount to authorize
|
||||
campaign: optional campaign object(to be set with TARGET_TYPE_CAMPAIGN)
|
||||
list: optional list object(to be set with TARGET_TYPE_LIST)
|
||||
user: optional user object
|
||||
return_url: url to redirect supporter to after a successful PayPal transaction
|
||||
nevermind_url: url to send supporter to if support hits cancel while in middle of PayPal transaction
|
||||
anonymous: whether this pledge is anonymous
|
||||
premium: the premium selected by the supporter for this transaction
|
||||
paymentReason: a memo line that will show up in the Payer's Amazon (and Paypal?) account
|
||||
modification: whether this authorize call is part of a modification of an existing pledge
|
||||
ack_name, ack_link, ack_dedication: how the user will be credited in the unglued ebook, if applicable
|
||||
|
||||
return value: a tuple of the new transaction object and a re-direct url. If the process fails,
|
||||
the redirect url will be None
|
||||
|
||||
'''
|
||||
|
||||
t = Transaction.objects.create(amount=amount,
|
||||
max_amount=amount,
|
||||
type=PAYMENT_TYPE_AUTHORIZATION,
|
||||
execution = EXECUTE_TYPE_CHAINED_DELAYED,
|
||||
target=target,
|
||||
currency=currency,
|
||||
status='NONE',
|
||||
campaign=campaign,
|
||||
list=list,
|
||||
user=user,
|
||||
anonymous=anonymous,
|
||||
premium=premium,
|
||||
ack_name=ack_name,
|
||||
ack_link=ack_link,
|
||||
ack_dedication=ack_dedication
|
||||
)
|
||||
'''
|
||||
|
||||
# we might want to not allow for a return_url or nevermind_url to be passed in but calculated
|
||||
if host==None:
|
||||
#TODO send user to select a payment processor
|
||||
pass
|
||||
|
||||
# we might want to not allow for a return_url to be passed in but calculated
|
||||
# here because we have immediate access to the Transaction object.
|
||||
|
||||
if nevermind_url is None:
|
||||
nevermind_path = "{0}?{1}".format(reverse('pledge_nevermind'),
|
||||
urllib.urlencode({'tid':t.id}))
|
||||
nevermind_url = urlparse.urljoin(settings.BASE_URL, nevermind_path)
|
||||
|
||||
if return_url is None:
|
||||
return_path = "{0}?{1}".format(reverse('pledge_complete'),
|
||||
|
@ -590,7 +565,7 @@ class PaymentManager( object ):
|
|||
return_url = urlparse.urljoin(settings.BASE_URL, return_path)
|
||||
|
||||
method = getattr(t.get_payment_class(), "Preapproval")
|
||||
p = method(t, amount, expiry, return_url=return_url, nevermind_url=nevermind_url, paymentReason=paymentReason)
|
||||
p = method(transaction, transaction.max_amount, expiry, return_url=return_url, paymentReason=paymentReason)
|
||||
|
||||
# Create a response for this
|
||||
envelope = p.envelope()
|
||||
|
@ -600,11 +575,11 @@ class PaymentManager( object ):
|
|||
correlation_id = p.correlation_id(),
|
||||
timestamp = p.timestamp(),
|
||||
info = p.raw_response,
|
||||
transaction=t)
|
||||
transaction=transaction)
|
||||
|
||||
if p.success() and not p.error():
|
||||
t.preapproval_key = p.key()
|
||||
t.save()
|
||||
transaction.preapproval_key = p.key()
|
||||
transaction.save()
|
||||
|
||||
url = p.next_url()
|
||||
|
||||
|
@ -624,16 +599,69 @@ class PaymentManager( object ):
|
|||
# send the notice here for now
|
||||
# this is actually premature since we're only about to send the user off to the payment system to
|
||||
# authorize a charge
|
||||
pledge_created.send(sender=self, transaction=t)
|
||||
pledge_created.send(sender=self, transaction=transaction)
|
||||
|
||||
return t, url
|
||||
return transaction, url
|
||||
|
||||
|
||||
else:
|
||||
t.error = p.error_string()
|
||||
t.save()
|
||||
transaction.error = p.error_string()
|
||||
transaction.save()
|
||||
logger.info("Authorize Error: " + p.error_string())
|
||||
return transaction, None
|
||||
|
||||
def process_transaction(self, currency, amount, host=None, campaign=None, user=None,
|
||||
return_url=None, anonymous=False, premium=None,
|
||||
paymentReason="unglue.it Pledge", ack_name=None, ack_dedication=None,
|
||||
modification=False):
|
||||
'''
|
||||
process
|
||||
|
||||
saves and processes a proposed transaction; decides if the transaction should be processed immediately.
|
||||
|
||||
currency: a 3-letter currency code, i.e. USD
|
||||
amount: the amount to authorize
|
||||
host: the name of the processing module; if none, send user back to decide!
|
||||
campaign: required campaign object
|
||||
user: optional user object
|
||||
return_url: url to redirect supporter to after a successful transaction
|
||||
anonymous: whether this pledge is anonymous
|
||||
premium: the premium selected by the supporter for this transaction
|
||||
paymentReason: a memo line that will show up in the Payer's Amazon (and Paypal?) account
|
||||
modification: whether this authorize call is part of a modification of an existing pledge
|
||||
ack_name, ack_dedication: how the user will be credited in the unglued ebook, if applicable
|
||||
|
||||
return value: a tuple of the new transaction object and a re-direct url. If the process fails,
|
||||
the redirect url will be None
|
||||
'''
|
||||
# set the expiry date based on the campaign deadline
|
||||
expiry = campaign.deadline + timedelta( days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN )
|
||||
|
||||
t = Transaction.objects.create(amount=0,
|
||||
max_amount=amount,
|
||||
currency=currency,
|
||||
status='NONE',
|
||||
campaign=campaign,
|
||||
user=user,
|
||||
anonymous=anonymous,
|
||||
premium=premium,
|
||||
ack_name=ack_name,
|
||||
ack_dedication=ack_dedication
|
||||
)
|
||||
|
||||
# does user have enough credit to pledge now?
|
||||
if user.credit.available >= amount :
|
||||
# YES!
|
||||
credit.pledge_transaction(t,user,amount)
|
||||
return_path = "{0}?{1}".format(reverse('pledge_complete'),
|
||||
urllib.urlencode({'tid':t.id}))
|
||||
return_url = urlparse.urljoin(settings.BASE_URL, return_path)
|
||||
pledge_created.send(sender=self, transaction=t)
|
||||
return t, return_url
|
||||
else:
|
||||
#TODO send user to choose payment path
|
||||
return t, None
|
||||
|
||||
|
||||
def cancel_related_transaction(self, transaction, status=TRANSACTION_STATUS_ACTIVE, campaign=None):
|
||||
'''
|
||||
|
@ -677,26 +705,29 @@ class PaymentManager( object ):
|
|||
|
||||
return canceled
|
||||
|
||||
def modify_transaction(self, transaction, amount, expiry=None, anonymous=None, premium=None,
|
||||
def modify_transaction(self, transaction, amount, expiry=None, premium=None,
|
||||
return_url=None, nevermind_url=None, paymentReason=None,
|
||||
ack_name=None, ack_link=None, ack_dedication=None):
|
||||
ack_name=None, ack_dedication=None, anonymous=None):
|
||||
'''
|
||||
modify
|
||||
|
||||
Modifies a transaction. The only type of modification allowed is to the amount and expiration date
|
||||
Modifies a transaction.
|
||||
2 main situations: if the new amount is less than max_amount, no need to go out to PayPal again
|
||||
if new amount is greater than max_amount...need to go out and get new approval.
|
||||
to start with, we can use the standard pledge_complete, pledge_cancel machinery
|
||||
might have to modify the pledge_complete, pledge_cancel because the messages are going to be
|
||||
different because we're modifying a pledge rather than a new one.
|
||||
|
||||
amount: the new amount
|
||||
expiry: the new expiration date, or if none the current expiration date will be used
|
||||
anonymous: new anonymous value; if None, then keep old value
|
||||
premium: new premium selected; if None, then keep old value
|
||||
return_url: the return URL after the preapproval(if needed)
|
||||
nevermind_url: the cancel url after the preapproval(if needed)
|
||||
paymentReason: a memo line that will show up in the Payer's Amazon (and Paypal?) account
|
||||
|
||||
return value: True if successful, False otherwise. An optional second parameter for the forward URL if a new authorhization is needed
|
||||
'''
|
||||
|
||||
# Can only modify the amount of a preapproval for now
|
||||
if transaction.type != PAYMENT_TYPE_AUTHORIZATION:
|
||||
logger.info("Error, attempt to modify an invalid transaction type")
|
||||
return False, None
|
||||
|
@ -707,34 +738,50 @@ class PaymentManager( object ):
|
|||
logger.info("Error, attempt to modify a transaction that is not active")
|
||||
return False, None
|
||||
|
||||
# if any of expiry, anonymous, or premium is None, use the existing value
|
||||
if expiry is None:
|
||||
expiry = transaction.date_expired
|
||||
if anonymous is None:
|
||||
anonymous = transaction.anonymous
|
||||
if premium is None:
|
||||
premium = transaction.premium
|
||||
|
||||
if amount > transaction.max_amount or expiry != transaction.date_expired:
|
||||
if transaction.host == PAYMENT_HOST_CREDIT:
|
||||
# does user have enough credit to pledge now?
|
||||
if transaction.user.credit.available >= amount-transaction.amount :
|
||||
# YES!
|
||||
transaction.anonymous = anonymous
|
||||
transaction.premium = premium
|
||||
transaction.ack_name = ack_name
|
||||
transaction.ack_dedication = ack_dedication
|
||||
credit.pledge_transaction(transaction,transaction.user,amount)
|
||||
return_path = "{0}?{1}".format(reverse('pledge_complete'),
|
||||
urllib.urlencode({'tid':transaction.id}))
|
||||
return_url = urlparse.urljoin(settings.BASE_URL, return_path)
|
||||
|
||||
# Start a new authorization for the new amount
|
||||
logger.info("Updated amount of transaction to %f" % amount)
|
||||
pledge_modified.send(sender=self, transaction=transaction,up_or_down="decreased" if amount-transaction.amount<0 else "increased")
|
||||
return transaction, return_url
|
||||
else:
|
||||
#TODO send user to choose payment path
|
||||
return t, None
|
||||
elif amount > transaction.max_amount or expiry != transaction.date_expired:
|
||||
|
||||
# set the expiry date based on the campaign deadline
|
||||
expiry = transaction.campaign.deadline + timedelta( days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN )
|
||||
|
||||
# Start a new transaction for the new amount
|
||||
t = Transaction.objects.create(amount=amount,
|
||||
max_amount=amount,
|
||||
host=transaction.host,
|
||||
currency=currency,
|
||||
status=TRANSACTION_STATUS_CREATED,
|
||||
campaign=transaction.campaign,
|
||||
user=transaction.user,
|
||||
anonymous=anonymous if anonymous!=None else transaction.anonymous,
|
||||
premium=premium if premium != None else transaction.premium,
|
||||
ack_name=ack_name,
|
||||
ack_dedication=ack_dedication
|
||||
)
|
||||
|
||||
t, url = self.authorize(transaction.currency,
|
||||
transaction.target,
|
||||
amount,
|
||||
expiry,
|
||||
transaction.campaign,
|
||||
transaction.list,
|
||||
transaction.user,
|
||||
return_url,
|
||||
nevermind_url,
|
||||
anonymous,
|
||||
premium,
|
||||
paymentReason,
|
||||
ack_name,
|
||||
ack_link,
|
||||
ack_dedication,
|
||||
True)
|
||||
t, url = self.authorize(transaction,
|
||||
expiry=expiry if expiry else transaction.date_expired,
|
||||
return_url=return_url,
|
||||
paymentReason=paymentReason,
|
||||
modification=True
|
||||
)
|
||||
|
||||
if t and url:
|
||||
# Need to re-direct to approve the transaction
|
||||
|
@ -762,7 +809,6 @@ class PaymentManager( object ):
|
|||
transaction.anonymous = anonymous
|
||||
transaction.premium = premium
|
||||
transaction.ack_name = ack_name
|
||||
transaction.ack_link = ack_link
|
||||
transaction.ack_dedication = ack_dedication
|
||||
|
||||
transaction.save()
|
||||
|
@ -820,16 +866,15 @@ class PaymentManager( object ):
|
|||
logger.info("Refund Transaction " + str(transaction.id) + " Failed with error: " + p.error_string())
|
||||
return False
|
||||
|
||||
def pledge(self, currency, target, receiver_list, campaign=None, list=None, user=None,
|
||||
def pledge(self, currency, receiver_list, campaign=None, user=None,
|
||||
return_url=None, nevermind_url=None, anonymous=False, premium=None, ack_name=None,
|
||||
ack_link=None, ack_dedication=None):
|
||||
ack_dedication=None):
|
||||
'''
|
||||
pledge
|
||||
|
||||
Performs an instant payment
|
||||
|
||||
currency: a 3-letter paypal currency code, i.e. USD
|
||||
target: a defined target type, i.e. TARGET_TYPE_CAMPAIGN, TARGET_TYPE_LIST, TARGET_TYPE_NONE
|
||||
receiver_list: a list of receivers for the transaction, in this format:
|
||||
|
||||
[
|
||||
|
@ -837,8 +882,7 @@ class PaymentManager( object ):
|
|||
{'email':'email-2', 'amount':amount2}
|
||||
]
|
||||
|
||||
campaign: optional campaign object(to be set with TARGET_TYPE_CAMPAIGN)
|
||||
list: optional list object(to be set with TARGET_TYPE_LIST)
|
||||
campaign: required campaign object
|
||||
user: optional user object
|
||||
return_url: url to redirect supporter to after a successful PayPal transaction
|
||||
nevermind_url: url to send supporter to if support hits cancel while in middle of PayPal transaction
|
||||
|
@ -863,13 +907,11 @@ class PaymentManager( object ):
|
|||
currency=currency,
|
||||
status='NONE',
|
||||
campaign=campaign,
|
||||
list=list,
|
||||
user=user,
|
||||
date_payment=now(),
|
||||
anonymous=anonymous,
|
||||
premium=premium,
|
||||
ack_name=ack_name,
|
||||
ack_link=ack_link,
|
||||
ack_dedication=ack_dedication
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'Credit'
|
||||
db.create_table('payment_credit', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('user', self.gf('django.db.models.fields.related.OneToOneField')(related_name='credit', unique=True, to=orm['auth.User'])),
|
||||
('balance', self.gf('django.db.models.fields.DecimalField')(default='0.00', max_digits=14, decimal_places=2)),
|
||||
('pledged', self.gf('django.db.models.fields.DecimalField')(default='0.00', max_digits=14, decimal_places=2)),
|
||||
('last_activity', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
|
||||
))
|
||||
db.send_create_signal('payment', ['Credit'])
|
||||
|
||||
# Adding model 'CreditLog'
|
||||
db.create_table('payment_creditlog', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True)),
|
||||
('amount', self.gf('django.db.models.fields.DecimalField')(default='0.00', max_digits=14, decimal_places=2)),
|
||||
('timestamp', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
|
||||
('action', self.gf('django.db.models.fields.CharField')(max_length=16)),
|
||||
))
|
||||
db.send_create_signal('payment', ['CreditLog'])
|
||||
|
||||
# Deleting field 'Transaction.target'
|
||||
db.delete_column('payment_transaction', 'target')
|
||||
|
||||
# Deleting field 'Transaction.list'
|
||||
db.delete_column('payment_transaction', 'list_id')
|
||||
|
||||
# Adding field 'Transaction.ack_name'
|
||||
db.add_column('payment_transaction', 'ack_name', self.gf('django.db.models.fields.CharField')(max_length=64, null=True), keep_default=False)
|
||||
|
||||
# Adding field 'Transaction.ack_dedication'
|
||||
db.add_column('payment_transaction', 'ack_dedication', self.gf('django.db.models.fields.CharField')(max_length=140, null=True), keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'Credit'
|
||||
db.delete_table('payment_credit')
|
||||
|
||||
# Deleting model 'CreditLog'
|
||||
db.delete_table('payment_creditlog')
|
||||
|
||||
# Adding field 'Transaction.target'
|
||||
db.add_column('payment_transaction', 'target', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
|
||||
|
||||
# Adding field 'Transaction.list'
|
||||
db.add_column('payment_transaction', 'list', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['core.Wishlist'], null=True), keep_default=False)
|
||||
|
||||
# Deleting field 'Transaction.ack_name'
|
||||
db.delete_column('payment_transaction', 'ack_name')
|
||||
|
||||
# Deleting field 'Transaction.ack_dedication'
|
||||
db.delete_column('payment_transaction', 'ack_dedication')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 8, 31, 2, 10, 24, 467332)'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 8, 31, 2, 10, 24, 467190)'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'core.campaign': {
|
||||
'Meta': {'object_name': 'Campaign'},
|
||||
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'deadline': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'description': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
|
||||
'details': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'null': 'True', 'to': "orm['core.Edition']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'license': ('django.db.models.fields.CharField', [], {'default': "'CC BY-NC-ND'", 'max_length': '255'}),
|
||||
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
|
||||
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True'}),
|
||||
'target': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.edition': {
|
||||
'Meta': {'object_name': 'Edition'},
|
||||
'cover_image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
|
||||
'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.Work']"})
|
||||
},
|
||||
'core.premium': {
|
||||
'Meta': {'object_name': 'Premium'},
|
||||
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
|
||||
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'limit': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
|
||||
},
|
||||
'core.work': {
|
||||
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
|
||||
'num_wishes': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
|
||||
},
|
||||
'payment.credit': {
|
||||
'Meta': {'object_name': 'Credit'},
|
||||
'balance': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_activity': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'pledged': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'credit'", 'unique': 'True', 'to': "orm['auth.User']"})
|
||||
},
|
||||
'payment.creditlog': {
|
||||
'Meta': {'object_name': 'CreditLog'},
|
||||
'action': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
|
||||
'amount': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
|
||||
},
|
||||
'payment.paymentresponse': {
|
||||
'Meta': {'object_name': 'PaymentResponse'},
|
||||
'api': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'correlation_id': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'info': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
|
||||
'timestamp': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
|
||||
'transaction': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['payment.Transaction']"})
|
||||
},
|
||||
'payment.receiver': {
|
||||
'Meta': {'object_name': 'Receiver'},
|
||||
'amount': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'currency': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
|
||||
'email': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'local_status': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}),
|
||||
'primary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'reason': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'transaction': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['payment.Transaction']"}),
|
||||
'txn_id': ('django.db.models.fields.CharField', [], {'max_length': '64'})
|
||||
},
|
||||
'payment.transaction': {
|
||||
'Meta': {'object_name': 'Transaction'},
|
||||
'ack_dedication': ('django.db.models.fields.CharField', [], {'max_length': '140', 'null': 'True'}),
|
||||
'ack_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}),
|
||||
'amount': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'approved': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Campaign']", 'null': 'True'}),
|
||||
'currency': ('django.db.models.fields.CharField', [], {'default': "'USD'", 'max_length': '10', 'null': 'True'}),
|
||||
'date_authorized': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'date_executed': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'date_expired': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'date_payment': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'error': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True'}),
|
||||
'execution': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'host': ('django.db.models.fields.CharField', [], {'default': "'none'", 'max_length': '32'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'local_status': ('django.db.models.fields.CharField', [], {'default': "'NONE'", 'max_length': '32', 'null': 'True'}),
|
||||
'max_amount': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'pay_key': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
|
||||
'preapproval_key': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
|
||||
'premium': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Premium']", 'null': 'True'}),
|
||||
'reason': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}),
|
||||
'receipt': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True'}),
|
||||
'secret': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'None'", 'max_length': '32'}),
|
||||
'type': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['payment']
|
|
@ -4,8 +4,11 @@ from django.conf import settings
|
|||
from regluit.core.models import Campaign, Wishlist, Premium
|
||||
from regluit.payment.parameters import *
|
||||
from regluit.payment.signals import credit_balance_added
|
||||
from decimal import Decimal
|
||||
from decimal import Decimal, NaN
|
||||
import uuid
|
||||
import urllib
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Transaction(models.Model):
|
||||
|
@ -14,16 +17,13 @@ class Transaction(models.Model):
|
|||
type = models.IntegerField(default=PAYMENT_TYPE_NONE, null=False)
|
||||
|
||||
# host: the payment processor. Named after the payment module that hosts the payment processing functions
|
||||
host = models.CharField(default=settings.PAYMENT_PROCESSOR, max_length=32, null=False)
|
||||
|
||||
# target: e.g, TARGET_TYPE_CAMPAIGN, TARGET_TYPE_LIST -- defined in parameters.py
|
||||
target = models.IntegerField(default=TARGET_TYPE_NONE, null=False)
|
||||
|
||||
host = models.CharField(default=PAYMENT_HOST_NONE, max_length=32, null=False)
|
||||
|
||||
#execution: e.g. EXECUTE_TYPE_CHAINED_INSTANT, EXECUTE_TYPE_CHAINED_DELAYED, EXECUTE_TYPE_PARALLEL
|
||||
execution = models.IntegerField(default=EXECUTE_TYPE_NONE, null=False)
|
||||
|
||||
# status: general status constants defined in parameters.py
|
||||
status = models.CharField(max_length=32, default='None', null=False)
|
||||
status = models.CharField(max_length=32, default=TRANSACTION_STATUS_NONE, null=False)
|
||||
|
||||
# local_status: status code specific to the payment processor
|
||||
local_status = models.CharField(max_length=32, default='NONE', null=True)
|
||||
|
@ -75,14 +75,14 @@ class Transaction(models.Model):
|
|||
|
||||
# how to acknowledge the user on the supporter page of the campaign ebook
|
||||
ack_name = models.CharField(max_length=64, null=True)
|
||||
ack_link = models.URLField(null=True)
|
||||
ack_dedication = models.CharField(max_length=140, null=True)
|
||||
|
||||
# whether the user wants to be not listed publicly
|
||||
anonymous = models.BooleanField(null=False)
|
||||
|
||||
# list: makes allowance for pledging against a Wishlist: not currently in use
|
||||
list = models.ForeignKey(Wishlist, null=True)
|
||||
|
||||
@property
|
||||
def ack_link(self):
|
||||
return 'https://unglue.it/supporter/%s'%urllib.urlencode(self.user.username)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.secret:
|
||||
|
@ -149,10 +149,17 @@ class Receiver(models.Model):
|
|||
def __unicode__(self):
|
||||
return u"Receiver -- email: {0} status: {1} transaction: {2}".format(self.email, self.status, unicode(self.transaction))
|
||||
|
||||
class CreditLog(models.Model):
|
||||
# a write only record of Donation Credit Transactions
|
||||
user = models.ForeignKey(User, null=True)
|
||||
amount = models.DecimalField(default=Decimal('0.00'), max_digits=14, decimal_places=2) # max 999,999,999,999.99
|
||||
timestamp = models.DateTimeField(auto_now=True)
|
||||
action = models.CharField(max_length=16)
|
||||
|
||||
class Credit(models.Model):
|
||||
user = models.OneToOneField(User, related_name='credit')
|
||||
balance = models.IntegerField(default=0)
|
||||
pledged = models.IntegerField(default=0)
|
||||
balance = models.DecimalField(default=Decimal('0.00'), max_digits=14, decimal_places=2) # max 999,999,999,999.99
|
||||
pledged = models.DecimalField(default=Decimal('0.00'), max_digits=14, decimal_places=2) # max 999,999,999,999.99
|
||||
last_activity = models.DateTimeField(auto_now=True)
|
||||
|
||||
@property
|
||||
|
@ -165,17 +172,29 @@ class Credit(models.Model):
|
|||
else:
|
||||
self.balance = self.balance + num_credits
|
||||
self.save()
|
||||
credit_balance_added.send(sender=self, amount=num_credits)
|
||||
try: # bad things can happen here if you don't return True
|
||||
CreditLog(user = self.user, amount = num_credits, action="add_to_balance").save()
|
||||
except:
|
||||
logger.exception("failed to log add_to_balance of %s", num_credits)
|
||||
try:
|
||||
credit_balance_added.send(sender=self, amount=num_credits)
|
||||
except:
|
||||
logger.exception("credit_balance_added failed of %s", num_credits)
|
||||
return True
|
||||
|
||||
def add_to_pledged(self, num_credits):
|
||||
if not isinstance( num_credits, int):
|
||||
num_credits=Decimal(num_credits)
|
||||
if num_credits is NaN:
|
||||
return False
|
||||
if self.balance - self.pledged < num_credits :
|
||||
return False
|
||||
else:
|
||||
self.pledged=self.pledged + num_credits
|
||||
self.save()
|
||||
try: # bad things can happen here if you don't return True
|
||||
CreditLog(user = self.user, amount = num_credits, action="add_to_pledged").save()
|
||||
except:
|
||||
logger.exception("failed to log add_to_pledged of %s", num_credits)
|
||||
return True
|
||||
|
||||
def use_pledge(self, num_credits):
|
||||
|
@ -187,6 +206,10 @@ class Credit(models.Model):
|
|||
self.pledged=self.pledged - num_credits
|
||||
self.balance = self.balance - num_credits
|
||||
self.save()
|
||||
try:
|
||||
CreditLog(user = self.user, amount = - num_credits, action="use_pledge").save()
|
||||
except:
|
||||
logger.exception("failed to log use_pledge of %s", num_credits)
|
||||
return True
|
||||
|
||||
def transfer_to(self, receiver, num_credits):
|
||||
|
|
|
@ -5,17 +5,15 @@ PAYMENT_TYPE_AUTHORIZATION = 2
|
|||
PAYMENT_HOST_NONE = "none"
|
||||
PAYMENT_HOST_PAYPAL = "paypal"
|
||||
PAYMENT_HOST_AMAZON = "amazon"
|
||||
PAYMENT_HOST_TEST = "test"
|
||||
PAYMENT_HOST_CREDIT = "credit"
|
||||
PAYMENT_HOST_STRIPE = "stripe"
|
||||
|
||||
EXECUTE_TYPE_NONE = 0
|
||||
EXECUTE_TYPE_CHAINED_INSTANT = 1
|
||||
EXECUTE_TYPE_CHAINED_DELAYED = 2
|
||||
EXECUTE_TYPE_PARALLEL = 3
|
||||
|
||||
TARGET_TYPE_NONE = 0
|
||||
TARGET_TYPE_CAMPAIGN = 1
|
||||
TARGET_TYPE_LIST = 2
|
||||
TARGET_TYPE_DONATION = 3
|
||||
|
||||
# The default status for a transaction that is newly created
|
||||
TRANSACTION_STATUS_NONE = 'None'
|
||||
|
||||
|
@ -47,6 +45,3 @@ TRANSACTION_STATUS_REFUNDED = 'Refunded'
|
|||
# The transaction was refused/denied
|
||||
TRANSACTION_STATUS_FAILED = 'Failed'
|
||||
|
||||
# these two following parameters are probably extraneous since I think we will compute dynamically where to return each time.
|
||||
COMPLETE_URL = '/paymentcomplete'
|
||||
NEVERMIND_URL = '/paymentnevermind'
|
||||
|
|
|
@ -190,7 +190,7 @@ class PledgeTest(TestCase):
|
|||
|
||||
# Note, set this to 1-5 different receivers with absolute amounts for each
|
||||
receiver_list = [{'email':settings.PAYPAL_GLUEJAR_EMAIL, 'amount':20.00}]
|
||||
t, url = p.pledge('USD', TARGET_TYPE_NONE, receiver_list, campaign=None, list=None, user=None)
|
||||
t, url = p.pledge('USD', receiver_list, campaign=None, list=None, user=None)
|
||||
|
||||
self.validateRedirect(t, url, 1)
|
||||
|
||||
|
@ -220,7 +220,7 @@ class PledgeTest(TestCase):
|
|||
receiver_list = [{'email':settings.PAYPAL_GLUEJAR_EMAIL, 'amount':20.00},
|
||||
{'email':settings.PAYPAL_TEST_RH_EMAIL, 'amount':10.00}]
|
||||
|
||||
t, url = p.pledge('USD', TARGET_TYPE_NONE, receiver_list, campaign=None, list=None, user=None)
|
||||
t, url = p.pledge('USD', receiver_list, campaign=None, list=None, user=None)
|
||||
|
||||
self.validateRedirect(t, url, 2)
|
||||
|
||||
|
@ -244,7 +244,7 @@ class PledgeTest(TestCase):
|
|||
|
||||
# Note, set this to 1-5 different receivers with absolute amounts for each
|
||||
receiver_list = [{'email':settings.PAYPAL_GLUEJAR_EMAIL, 'amount':50000.00}]
|
||||
t, url = p.pledge('USD', TARGET_TYPE_NONE, receiver_list, campaign=None, list=None, user=None)
|
||||
t, url = p.pledge('USD', receiver_list, campaign=None, list=None, user=None)
|
||||
|
||||
self.validateRedirect(t, url, 1)
|
||||
|
||||
|
@ -284,7 +284,7 @@ class AuthorizeTest(TestCase):
|
|||
|
||||
# Note, set this to 1-5 different receivers with absolute amounts for each
|
||||
|
||||
t, url = p.authorize('USD', TARGET_TYPE_NONE, 100.0, campaign=None, list=None, user=None)
|
||||
t, url = p.authorize('USD', 100.0, campaign=None, list=None, user=None)
|
||||
|
||||
self.validateRedirect(t, url)
|
||||
|
||||
|
@ -388,7 +388,7 @@ class BasicGuiTest(TestCase):
|
|||
def suite():
|
||||
|
||||
#testcases = [PledgeTest, AuthorizeTest, TransactionTest]
|
||||
testcases = [TransactionTest]
|
||||
testcases = [TransactionTest, CreditTest]
|
||||
suites = unittest.TestSuite([unittest.TestLoader().loadTestsFromTestCase(testcase) for testcase in testcases])
|
||||
return suites
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@ if settings.DEBUG:
|
|||
url(r"^testexecute", "testExecute"),
|
||||
url(r"^testcancel", "testCancel"),
|
||||
url(r"^querycampaign", "queryCampaign"),
|
||||
url(r"^runtests", "runTests"),
|
||||
url(r"^paymentcomplete","paymentcomplete"),
|
||||
url(r"^checkstatus", "checkStatus"),
|
||||
url(r"^testfinish", "testFinish"),
|
||||
url(r"^testrefund", "testRefund"),
|
||||
|
|
|
@ -13,7 +13,8 @@ from django.test.utils import setup_test_environment
|
|||
from django.template import RequestContext
|
||||
|
||||
from unittest import TestResult
|
||||
from regluit.payment.tests import PledgeTest, AuthorizeTest
|
||||
|
||||
|
||||
import uuid
|
||||
from decimal import Decimal as D
|
||||
|
||||
|
@ -112,12 +113,8 @@ def testAuthorize(request):
|
|||
receiver_list = [{'email': TEST_RECEIVERS[0], 'amount':20.00},
|
||||
{'email': TEST_RECEIVERS[1], 'amount':10.00}]
|
||||
|
||||
if campaign_id:
|
||||
campaign = Campaign.objects.get(id=int(campaign_id))
|
||||
t, url = p.authorize('USD', TARGET_TYPE_CAMPAIGN, amount, campaign=campaign, return_url=None, list=None, user=None)
|
||||
|
||||
else:
|
||||
t, url = p.authorize('USD', TARGET_TYPE_NONE, amount, campaign=None, return_url=None, list=None, user=None)
|
||||
campaign = Campaign.objects.get(id=int(campaign_id))
|
||||
t, url = p.authorize('USD', amount, campaign=campaign, return_url=None, list=None, user=None)
|
||||
|
||||
if url:
|
||||
logger.info("testAuthorize: " + url)
|
||||
|
@ -248,12 +245,9 @@ def testPledge(request):
|
|||
else:
|
||||
receiver_list = [{'email':TEST_RECEIVERS[0], 'amount':78.90}, {'email':TEST_RECEIVERS[1], 'amount':34.56}]
|
||||
|
||||
if campaign_id:
|
||||
campaign = Campaign.objects.get(id=int(campaign_id))
|
||||
t, url = p.pledge('USD', TARGET_TYPE_CAMPAIGN, receiver_list, campaign=campaign, list=None, user=user, return_url=None)
|
||||
campaign = Campaign.objects.get(id=int(campaign_id))
|
||||
t, url = p.pledge('USD', receiver_list, campaign=campaign, list=None, user=user, return_url=None)
|
||||
|
||||
else:
|
||||
t, url = p.pledge('USD', TARGET_TYPE_NONE, receiver_list, campaign=None, list=None, user=user, return_url=None)
|
||||
|
||||
if url:
|
||||
logger.info("testPledge: " + url)
|
||||
|
@ -264,33 +258,6 @@ def testPledge(request):
|
|||
logger.info("testPledge: Error " + str(t.error))
|
||||
return HttpResponse(response)
|
||||
|
||||
def runTests(request):
|
||||
|
||||
try:
|
||||
# Setup the test environement. We need to run these tests on a live server
|
||||
# so our code can receive IPN notifications from paypal
|
||||
setup_test_environment()
|
||||
result = TestResult()
|
||||
|
||||
# Run the authorize test
|
||||
test = AuthorizeTest('test_authorize')
|
||||
test.run(result)
|
||||
|
||||
# Run the pledge test
|
||||
test = PledgeTest('test_pledge_single_receiver')
|
||||
test.run(result)
|
||||
|
||||
# Run the pledge failure test
|
||||
test = PledgeTest('test_pledge_too_much')
|
||||
test.run(result)
|
||||
|
||||
output = "Tests Run: " + str(result.testsRun) + str(result.errors) + str(result.failures)
|
||||
logger.info(output)
|
||||
|
||||
return HttpResponse(output)
|
||||
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
@csrf_exempt
|
||||
def handleIPN(request, module):
|
||||
|
@ -303,11 +270,6 @@ def handleIPN(request, module):
|
|||
return HttpResponse("ipn")
|
||||
|
||||
|
||||
def paymentcomplete(request):
|
||||
# pick up all get and post parameters and display
|
||||
output = "payment complete"
|
||||
output += request.method + "\n" + str(request.REQUEST.items())
|
||||
return HttpResponse(output)
|
||||
|
||||
def checkStatus(request):
|
||||
# Check the status of all PAY transactions and flag any errors
|
||||
|
|
Loading…
Reference in New Issue