1
|
from datetime import datetime
|
2
|
from decimal import Decimal
|
3
|
|
4
|
from django.db import models
|
5
|
from django.core.urlresolvers import reverse
|
6
|
from django.utils.translation import ugettext_lazy as _, pgettext_lazy
|
7
|
from django.template import RequestContext
|
8
|
from django.template import Template
|
9
|
|
10
|
from jsonfield import JSONField
|
11
|
|
12
|
from cmsplugin_blurp.renderers.data_source import Data
|
13
|
|
14
|
import requests
|
15
|
import eopayment
|
16
|
|
17
|
SERVICES = ((eopayment.SIPS, 'SIPS'),
|
18
|
(eopayment.SYSTEMPAY, 'SYSTEMPAY'),
|
19
|
(eopayment.SPPLUS, 'SPPLUS'),
|
20
|
(eopayment.TIPI, 'TIPI'),
|
21
|
(eopayment.DUMMY, 'DUMMY'),
|
22
|
)
|
23
|
|
24
|
TRANSACTION_STATUS_PROD = (
|
25
|
('CREATED', 'CREATED'),
|
26
|
('PAID', 'PAID'),
|
27
|
('DENIED', 'DENIED'),
|
28
|
('CANCELED', 'CANCELED'),
|
29
|
('ERROR', 'ERROR'),
|
30
|
)
|
31
|
TRANSACTION_STATUS_TEST = tuple((('TEST_%s' % k, 'TEST_%s' %v)
|
32
|
for k,v in TRANSACTION_STATUS_PROD))
|
33
|
TRANSACTION_STATUS = TRANSACTION_STATUS_PROD + TRANSACTION_STATUS_TEST
|
34
|
|
35
|
|
36
|
class Regie(models.Model):
|
37
|
label = models.CharField(max_length=64)
|
38
|
slug = models.SlugField(unique=True)
|
39
|
description = models.TextField()
|
40
|
service = models.CharField(max_length=64, choices=SERVICES)
|
41
|
invoice_get_url = models.CharField(max_length=256, help_text=_('Get an invoice from this Regie'))
|
42
|
invoice_update_url = models.CharField(max_length=256, help_text=_('Update an invoice of this Regie'))
|
43
|
invoice_list_url = models.CharField(max_length=256, blank=True, null=True,
|
44
|
help_text=_("Get a list of invoices "\
|
45
|
"(RequestContext dependent, typically user's invoices)"))
|
46
|
|
47
|
def natural_key(self):
|
48
|
return (self.slug,)
|
49
|
|
50
|
def __unicode__(self):
|
51
|
return self.label
|
52
|
|
53
|
def get_invoice_url(self, context):
|
54
|
return Template(self.invoice_get_url).render(context)
|
55
|
|
56
|
def get_invoice_update_url(self, context):
|
57
|
return Template(self.invoice_update_url).render(context)
|
58
|
|
59
|
def get_invoice_list_url(self, context):
|
60
|
return Template(self.invoice_list_url).render(context)
|
61
|
|
62
|
def get_invoice_list(self, request, **kwargs):
|
63
|
if not self.invoice_list_url:
|
64
|
return []
|
65
|
context = RequestContext(request, kwargs)
|
66
|
data_source = Data(self.slug, {'limit': None, 'refresh': None},
|
67
|
{'url': self.get_invoice_list_url(context),
|
68
|
'content_type': 'application/json',
|
69
|
'parser_type': 'json',
|
70
|
'auth_mech': 'oauth2',
|
71
|
'redirects': True,
|
72
|
'slug': 'invoice_list'}, context)
|
73
|
content = data_source.update_content()
|
74
|
return content.get('data', {}).get('invoices', [])
|
75
|
|
76
|
def get_invoice(self, invoice_id, invoice_hash=None, request=None):
|
77
|
'''get an invoice (dict), via webservice
|
78
|
invoice_hash: a key to access the invoice (for example a password)
|
79
|
'''
|
80
|
context = {'regie': self,
|
81
|
'invoice_id': invoice_id,
|
82
|
'invoice_hash': invoice_hash}
|
83
|
if request:
|
84
|
context = RequestContext(request, context)
|
85
|
data_source = Data(self.slug, {'limit': None, 'refresh': None},
|
86
|
{'url': self.get_invoice_url(context),
|
87
|
'content_type': 'application/json',
|
88
|
'parser_type': 'json',
|
89
|
'slug': 'invoice'}, context)
|
90
|
content = data_source.update_content()
|
91
|
invoice = content.get('data', {}).get('invoice', {})
|
92
|
if invoice:
|
93
|
invoice['url'] = reverse('transaction',
|
94
|
args=(self.slug, invoice_id, invoice_hash))
|
95
|
# is this invoice in the list of invoices ? (typically, list
|
96
|
# of user's invoices). If yes, add a "download_url" value
|
97
|
if self.invoice_list_url and request and request.user.is_authenticated():
|
98
|
invoice['in_list'] = False
|
99
|
ctx_invoices = self.get_invoice_list(request)
|
100
|
for i in ctx_invoices:
|
101
|
if i['id'] == invoice['id']:
|
102
|
invoice['download_url'] = reverse('invoice-download',
|
103
|
args=(self.slug, invoice_id, invoice_hash))
|
104
|
break
|
105
|
# convert values to proper datatypes
|
106
|
for amount_key in ('paid_amount', 'total_amount', 'amount'):
|
107
|
if invoice.get(amount_key):
|
108
|
invoice[amount_key] = Decimal(invoice[amount_key])
|
109
|
for date_key in ('creation_date', 'expiration_date', 'paid_date',
|
110
|
'tipi_paid_date'):
|
111
|
if invoice.get(date_key):
|
112
|
invoice[date_key] = datetime.strptime(invoice[date_key], '%Y-%m-%d')
|
113
|
return invoice
|
114
|
|
115
|
|
116
|
class Option(models.Model):
|
117
|
regie = models.ForeignKey(Regie)
|
118
|
name = models.CharField(max_length=32)
|
119
|
value = models.CharField(max_length=256)
|
120
|
|
121
|
class Meta:
|
122
|
abstract = True
|
123
|
|
124
|
def __unicode__(self):
|
125
|
return _('%s: %s') % (self.name, self.value)
|
126
|
|
127
|
class ServiceOption(Option):
|
128
|
pass
|
129
|
|
130
|
class RequestOption(Option):
|
131
|
pass
|
132
|
|
133
|
class TransactionEvent(models.Model):
|
134
|
regie = models.ForeignKey(Regie)
|
135
|
transaction_id = models.CharField(max_length=128, db_index=True)
|
136
|
invoice_id= models.CharField(max_length=128, db_index=True)
|
137
|
date = models.DateTimeField(auto_now_add=True)
|
138
|
address = models.GenericIPAddressField(null=True, blank=True)
|
139
|
nameid = models.CharField(max_length=256, null=True, blank=True)
|
140
|
status = models.CharField(max_length=16, choices=TRANSACTION_STATUS,
|
141
|
default='CREATED')
|
142
|
response = models.BooleanField(default=False)
|
143
|
details = JSONField(blank=True, null=True)
|
144
|
|
145
|
class Meta:
|
146
|
get_latest_by = 'date'
|
147
|
ordering = ['date']
|
148
|
verbose_name = _('Transaction event')
|
149
|
verbose_name_plural = _('Transaction events')
|
150
|
|