initial commit
This commit is contained in:
commit
3e632c703b
|
@ -0,0 +1,3 @@
|
|||
git+git://repos.entrouvert.org/python-entrouvert
|
||||
git+git://repos.entrouvert.org/portail-citoyen2
|
||||
gunicorn
|
|
@ -0,0 +1,125 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
''' Setup script for Facturier app
|
||||
'''
|
||||
|
||||
import glob
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
from setuptools.command.install_lib import install_lib as _install_lib
|
||||
from distutils.command.build import build as _build
|
||||
from distutils.command.sdist import sdist
|
||||
from distutils.cmd import Command
|
||||
|
||||
class compile_translations(Command):
|
||||
description = 'compile message catalogs to MO files via django compilemessages'
|
||||
user_options = []
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
from django.core.management.commands.compilemessages import \
|
||||
compile_messages
|
||||
for path in ['src']:
|
||||
if not os.path.exists(os.path.join(path, 'locale')):
|
||||
continue
|
||||
curdir = os.getcwd()
|
||||
os.chdir(os.path.realpath(path))
|
||||
compile_messages(sys.stderr)
|
||||
os.chdir(curdir)
|
||||
|
||||
|
||||
class build(_build):
|
||||
sub_commands = [('compile_translations', None)] + _build.sub_commands
|
||||
|
||||
|
||||
class eo_sdist(sdist):
|
||||
|
||||
def run(self):
|
||||
print "creating VERSION file"
|
||||
if os.path.exists('VERSION'):
|
||||
os.remove('VERSION')
|
||||
version = get_version()
|
||||
version_file = open('VERSION', 'w')
|
||||
version_file.write(version)
|
||||
version_file.close()
|
||||
sdist.run(self)
|
||||
print "removing VERSION file"
|
||||
if os.path.exists('VERSION'):
|
||||
os.remove('VERSION')
|
||||
|
||||
|
||||
class install_lib(_install_lib):
|
||||
def run(self):
|
||||
self.run_command('compile_translations')
|
||||
_install_lib.run(self)
|
||||
|
||||
|
||||
def get_version():
|
||||
|
||||
version = None
|
||||
if os.path.exists('VERSION'):
|
||||
version_file = open('VERSION', 'r')
|
||||
version = version_file.read()
|
||||
version_file.close()
|
||||
return version
|
||||
for d in glob.glob('*'):
|
||||
if not os.path.isdir(d):
|
||||
continue
|
||||
module_file = os.path.join(d, '__init__.py')
|
||||
if not os.path.exists(module_file):
|
||||
continue
|
||||
for v in re.findall("""__version__ *= *['"](.*)['"]""",
|
||||
open(module_file).read()):
|
||||
assert version is None
|
||||
version = v
|
||||
if version:
|
||||
break
|
||||
assert version is not None
|
||||
if os.path.exists('.git'):
|
||||
import subprocess
|
||||
p = subprocess.Popen(['git','describe','--dirty','--match=v*'],
|
||||
stdout=subprocess.PIPE)
|
||||
result = p.communicate()[0]
|
||||
assert p.returncode == 0, 'git returned non-zero'
|
||||
new_version = result.split()[0][1:]
|
||||
assert not new_version.endswith('-dirty'), 'git workdir is not clean'
|
||||
assert new_version.split('-')[0] == version, '__version__ must match the last git annotated tag'
|
||||
version = new_version.replace('-', '.')
|
||||
return version
|
||||
|
||||
|
||||
setup(name="facturier",
|
||||
version=get_version(),
|
||||
license="AGPLv3 or later",
|
||||
description="Payment lib pluggable into portail-citoyen",
|
||||
author="Entr'ouvert",
|
||||
author_email="info@entrouvert.org",
|
||||
maintainer="Entr'ouvert",
|
||||
maintainer_email="info@entrouvert.com",
|
||||
include_package_data=True,
|
||||
packages=find_packages(),
|
||||
install_requires=[
|
||||
'portail-citoyen2',
|
||||
'gunicorn',
|
||||
'eopayment',
|
||||
'django-jsonfield',
|
||||
],
|
||||
dependency_links = [
|
||||
'git+git://repos.entrouvert.org/portail-citoyen2',
|
||||
'git+git://repos.entrouvert.org/python-entrouvert'
|
||||
],
|
||||
cmdclass={'build': build, 'install_lib': install_lib,
|
||||
'compile_translations': compile_translations,
|
||||
'sdist': eo_sdist},
|
||||
entry_points={
|
||||
'portail_citoyen2.plugin': ['facturier = facturier:Plugin']
|
||||
}
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
__version__ = '0.0.1'
|
||||
|
||||
class Plugin(object):
|
||||
def get_pre_urls(self):
|
||||
from . import urls
|
||||
return urls.urlpatterns
|
||||
|
||||
def get_apps(self):
|
||||
return [__name__]
|
||||
|
||||
def get_admin_modules(self):
|
||||
from . import dashboard
|
||||
return dashboard.get_admin_modules()
|
|
@ -0,0 +1,29 @@
|
|||
from .models import Regie, ServiceOption, RequestOption
|
||||
from .models import TransactionEvent
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
class RequestOptionInline(admin.TabularInline):
|
||||
model = RequestOption
|
||||
|
||||
class ServiceOptionInline(admin.TabularInline):
|
||||
model = ServiceOption
|
||||
|
||||
class RegieAdmin(admin.ModelAdmin):
|
||||
prepopulated_fields = {"slug": ("label",)}
|
||||
list_display = ('label', 'service')
|
||||
list_filter = ('service',)
|
||||
inlines = (ServiceOptionInline, RequestOptionInline)
|
||||
extras = 3
|
||||
|
||||
class TransactionEventAdmin(admin.ModelAdmin):
|
||||
date_hierarchy = 'date'
|
||||
list_display = ('date', 'transaction_id', 'regie', 'invoice_id', 'status',
|
||||
'response', 'details')
|
||||
list_filter = ('regie', 'response')
|
||||
readonly_fields = ('date', 'transaction_id', 'regie', 'invoice_id',
|
||||
'status', 'response', 'details', 'address', 'nameid')
|
||||
search_fields = ('invoice_id', 'details', 'address', 'nameid')
|
||||
|
||||
admin.site.register(Regie, RegieAdmin)
|
||||
admin.site.register(TransactionEvent, TransactionEventAdmin)
|
|
@ -0,0 +1,36 @@
|
|||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
class AppSettings(object):
|
||||
'''Thanks you, django-allauth'''
|
||||
__SENTINEL = object()
|
||||
|
||||
def __init__(self, prefix):
|
||||
self.prefix = prefix
|
||||
|
||||
def _setting(self, name, dflt=__SENTINEL):
|
||||
from django.conf import settings
|
||||
v = getattr(settings, self.prefix + name, dflt)
|
||||
if v is self.__SENTINEL:
|
||||
raise ImproperlyConfigured('Missing setting %r' % (self.prefix + name))
|
||||
return v
|
||||
|
||||
@property
|
||||
def download_filename(self):
|
||||
return self._setting('DOWNLOAD_FILENAME',
|
||||
'/var/lib/invoices/invoice_{invoice[id]}.pdf')
|
||||
|
||||
@property
|
||||
def download_filename_mimetype(self):
|
||||
return self._setting('DOWNLOAD_FILENAME_MIMETYPE', 'application/pdf')
|
||||
|
||||
@property
|
||||
def responses_csv_key(self):
|
||||
return self._setting('RESPONSES_CSV_KEY')
|
||||
|
||||
|
||||
app_settings = AppSettings('FACTURIER_')
|
||||
app_settings.__name__ = __name__
|
||||
sys.modules[__name__] = app_settings
|
Binary file not shown.
|
@ -0,0 +1,27 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-03-26 16:22+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: models.py:88
|
||||
msgid "Transaction event"
|
||||
msgstr "Evenement sur une transaction"
|
||||
|
||||
#: models.py:89
|
||||
msgid "Transaction events"
|
||||
msgstr "Evenements sur les transactions"
|
|
@ -0,0 +1,115 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as 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 'Regie'
|
||||
db.create_table(u'facturier_regie', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('label', self.gf('django.db.models.fields.CharField')(max_length=64)),
|
||||
('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50)),
|
||||
('description', self.gf('django.db.models.fields.TextField')()),
|
||||
('service', self.gf('django.db.models.fields.CharField')(max_length=64)),
|
||||
('get_url', self.gf('django.db.models.fields.related.ForeignKey')(related_name='regie_get', to=orm['data_source_plugin.DataSource'])),
|
||||
('update_url', self.gf('django.db.models.fields.related.ForeignKey')(related_name='regie_update', to=orm['data_source_plugin.DataSource'])),
|
||||
))
|
||||
db.send_create_signal(u'facturier', ['Regie'])
|
||||
|
||||
# Adding model 'ServiceOption'
|
||||
db.create_table(u'facturier_serviceoption', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('regie', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['facturier.Regie'])),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=32)),
|
||||
('value', self.gf('django.db.models.fields.CharField')(max_length=256)),
|
||||
))
|
||||
db.send_create_signal(u'facturier', ['ServiceOption'])
|
||||
|
||||
# Adding model 'RequestOption'
|
||||
db.create_table(u'facturier_requestoption', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('regie', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['facturier.Regie'])),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=32)),
|
||||
('value', self.gf('django.db.models.fields.CharField')(max_length=256)),
|
||||
))
|
||||
db.send_create_signal(u'facturier', ['RequestOption'])
|
||||
|
||||
# Adding model 'TransactionEvent'
|
||||
db.create_table(u'facturier_transactionevent', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('transaction_id', self.gf('django.db.models.fields.CharField')(max_length=128, db_index=True)),
|
||||
('invoice_id', self.gf('django.db.models.fields.CharField')(max_length=128, db_index=True)),
|
||||
('date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
|
||||
('event', self.gf('django.db.models.fields.CharField')(max_length=16)),
|
||||
('details', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
|
||||
))
|
||||
db.send_create_signal(u'facturier', ['TransactionEvent'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'Regie'
|
||||
db.delete_table(u'facturier_regie')
|
||||
|
||||
# Deleting model 'ServiceOption'
|
||||
db.delete_table(u'facturier_serviceoption')
|
||||
|
||||
# Deleting model 'RequestOption'
|
||||
db.delete_table(u'facturier_requestoption')
|
||||
|
||||
# Deleting model 'TransactionEvent'
|
||||
db.delete_table(u'facturier_transactionevent')
|
||||
|
||||
|
||||
models = {
|
||||
u'data_source_plugin.datasource': {
|
||||
'Meta': {'ordering': "('name',)", 'object_name': 'DataSource'},
|
||||
'allow_redirects': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'hash_algo': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'signature_key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
|
||||
'timeout': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
|
||||
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'verify_certificate': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
u'facturier.regie': {
|
||||
'Meta': {'object_name': 'Regie'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'get_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_get'", 'to': u"orm['data_source_plugin.DataSource']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'service': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
|
||||
'update_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_update'", 'to': u"orm['data_source_plugin.DataSource']"})
|
||||
},
|
||||
u'facturier.requestoption': {
|
||||
'Meta': {'object_name': 'RequestOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.serviceoption': {
|
||||
'Meta': {'object_name': 'ServiceOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.transactionevent': {
|
||||
'Meta': {'object_name': 'TransactionEvent'},
|
||||
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'details': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'event': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'invoice_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
|
||||
'transaction_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['facturier']
|
|
@ -0,0 +1,78 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Deleting field 'TransactionEvent.event'
|
||||
db.delete_column(u'facturier_transactionevent', 'event')
|
||||
|
||||
# Adding field 'TransactionEvent.status'
|
||||
db.add_column(u'facturier_transactionevent', 'status',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=16),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Adding field 'TransactionEvent.event'
|
||||
db.add_column(u'facturier_transactionevent', 'event',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=16),
|
||||
keep_default=False)
|
||||
|
||||
# Deleting field 'TransactionEvent.status'
|
||||
db.delete_column(u'facturier_transactionevent', 'status')
|
||||
|
||||
|
||||
models = {
|
||||
u'data_source_plugin.datasource': {
|
||||
'Meta': {'ordering': "('name',)", 'object_name': 'DataSource'},
|
||||
'allow_redirects': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'hash_algo': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'signature_key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
|
||||
'timeout': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
|
||||
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'verify_certificate': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
u'facturier.regie': {
|
||||
'Meta': {'object_name': 'Regie'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'get_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_get'", 'to': u"orm['data_source_plugin.DataSource']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'service': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
|
||||
'update_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_update'", 'to': u"orm['data_source_plugin.DataSource']"})
|
||||
},
|
||||
u'facturier.requestoption': {
|
||||
'Meta': {'object_name': 'RequestOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.serviceoption': {
|
||||
'Meta': {'object_name': 'ServiceOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.transactionevent': {
|
||||
'Meta': {'object_name': 'TransactionEvent'},
|
||||
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'details': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'invoice_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
|
||||
'transaction_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['facturier']
|
|
@ -0,0 +1,80 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding field 'TransactionEvent.address'
|
||||
db.add_column(u'facturier_transactionevent', 'address',
|
||||
self.gf('django.db.models.fields.GenericIPAddressField')(max_length=39, null=True, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'TransactionEvent.nameid'
|
||||
db.add_column(u'facturier_transactionevent', 'nameid',
|
||||
self.gf('django.db.models.fields.CharField')(max_length=256, null=True, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting field 'TransactionEvent.address'
|
||||
db.delete_column(u'facturier_transactionevent', 'address')
|
||||
|
||||
# Deleting field 'TransactionEvent.nameid'
|
||||
db.delete_column(u'facturier_transactionevent', 'nameid')
|
||||
|
||||
|
||||
models = {
|
||||
u'data_source_plugin.datasource': {
|
||||
'Meta': {'ordering': "('name',)", 'object_name': 'DataSource'},
|
||||
'allow_redirects': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'hash_algo': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'signature_key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
|
||||
'timeout': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
|
||||
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'verify_certificate': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
u'facturier.regie': {
|
||||
'Meta': {'object_name': 'Regie'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'get_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_get'", 'to': u"orm['data_source_plugin.DataSource']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'service': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
|
||||
'update_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_update'", 'to': u"orm['data_source_plugin.DataSource']"})
|
||||
},
|
||||
u'facturier.requestoption': {
|
||||
'Meta': {'object_name': 'RequestOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.serviceoption': {
|
||||
'Meta': {'object_name': 'ServiceOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.transactionevent': {
|
||||
'Meta': {'ordering': "['date']", 'object_name': 'TransactionEvent'},
|
||||
'address': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
|
||||
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'details': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'invoice_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
|
||||
'nameid': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'CREATED'", 'max_length': '16'}),
|
||||
'transaction_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['facturier']
|
|
@ -0,0 +1,71 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding field 'TransactionEvent.regie'
|
||||
db.add_column(u'facturier_transactionevent', 'regie',
|
||||
self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['facturier.Regie']),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting field 'TransactionEvent.regie'
|
||||
db.delete_column(u'facturier_transactionevent', 'regie_id')
|
||||
|
||||
|
||||
models = {
|
||||
u'data_source_plugin.datasource': {
|
||||
'Meta': {'ordering': "('name',)", 'object_name': 'DataSource'},
|
||||
'hash_algo': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'signature_key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
|
||||
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024'}),
|
||||
'verify_certificate': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
u'facturier.regie': {
|
||||
'Meta': {'object_name': 'Regie'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'get_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_get'", 'to': u"orm['data_source_plugin.DataSource']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'service': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
|
||||
'update_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_update'", 'to': u"orm['data_source_plugin.DataSource']"})
|
||||
},
|
||||
u'facturier.requestoption': {
|
||||
'Meta': {'object_name': 'RequestOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.serviceoption': {
|
||||
'Meta': {'object_name': 'ServiceOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.transactionevent': {
|
||||
'Meta': {'ordering': "['date']", 'object_name': 'TransactionEvent'},
|
||||
'address': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
|
||||
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'details': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'invoice_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
|
||||
'nameid': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'CREATED'", 'max_length': '16'}),
|
||||
'transaction_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['facturier']
|
|
@ -0,0 +1,72 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding field 'Regie.get_list_url'
|
||||
db.add_column(u'facturier_regie', 'get_list_url',
|
||||
self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='regie_get_list', null=True, to=orm['data_source_plugin.DataSource']),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting field 'Regie.get_list_url'
|
||||
db.delete_column(u'facturier_regie', 'get_list_url_id')
|
||||
|
||||
|
||||
models = {
|
||||
u'data_source_plugin.datasource': {
|
||||
'Meta': {'ordering': "('name',)", 'object_name': 'DataSource'},
|
||||
'hash_algo': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'signature_key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
|
||||
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024'}),
|
||||
'verify_certificate': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
u'facturier.regie': {
|
||||
'Meta': {'object_name': 'Regie'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'get_list_url': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'regie_get_list'", 'null': 'True', 'to': u"orm['data_source_plugin.DataSource']"}),
|
||||
'get_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_get'", 'to': u"orm['data_source_plugin.DataSource']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'service': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
|
||||
'update_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_update'", 'to': u"orm['data_source_plugin.DataSource']"})
|
||||
},
|
||||
u'facturier.requestoption': {
|
||||
'Meta': {'object_name': 'RequestOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.serviceoption': {
|
||||
'Meta': {'object_name': 'ServiceOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.transactionevent': {
|
||||
'Meta': {'ordering': "['date']", 'object_name': 'TransactionEvent'},
|
||||
'address': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
|
||||
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'details': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'invoice_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
|
||||
'nameid': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'CREATED'", 'max_length': '16'}),
|
||||
'transaction_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['facturier']
|
|
@ -0,0 +1,79 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding field 'TransactionEvent.response'
|
||||
db.add_column(u'facturier_transactionevent', 'response',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
# Changing field 'TransactionEvent.details'
|
||||
db.alter_column(u'facturier_transactionevent', 'details', self.gf('jsonfield.fields.JSONField')(null=True))
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting field 'TransactionEvent.response'
|
||||
db.delete_column(u'facturier_transactionevent', 'response')
|
||||
|
||||
|
||||
# Changing field 'TransactionEvent.details'
|
||||
db.alter_column(u'facturier_transactionevent', 'details', self.gf('django.db.models.fields.TextField')(null=True))
|
||||
|
||||
models = {
|
||||
u'data_source_plugin.datasource': {
|
||||
'Meta': {'ordering': "('name',)", 'object_name': 'DataSource'},
|
||||
'hash_algo': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'signature_key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
|
||||
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024'}),
|
||||
'verify_certificate': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
u'facturier.regie': {
|
||||
'Meta': {'object_name': 'Regie'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'get_list_url': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'regie_get_list'", 'null': 'True', 'to': u"orm['data_source_plugin.DataSource']"}),
|
||||
'get_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_get'", 'to': u"orm['data_source_plugin.DataSource']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'service': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
|
||||
'update_url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'regie_update'", 'to': u"orm['data_source_plugin.DataSource']"})
|
||||
},
|
||||
u'facturier.requestoption': {
|
||||
'Meta': {'object_name': 'RequestOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.serviceoption': {
|
||||
'Meta': {'object_name': 'ServiceOption'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '256'})
|
||||
},
|
||||
u'facturier.transactionevent': {
|
||||
'Meta': {'ordering': "['date']", 'object_name': 'TransactionEvent'},
|
||||
'address': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
|
||||
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'details': ('jsonfield.fields.JSONField', [], {'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'invoice_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
|
||||
'nameid': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'regie': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['facturier.Regie']"}),
|
||||
'response': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'CREATED'", 'max_length': '16'}),
|
||||
'transaction_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['facturier']
|
|
@ -0,0 +1,122 @@
|
|||
from django.db import models
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _, pgettext_lazy
|
||||
from django.template import RequestContext
|
||||
from jsonfield import JSONField
|
||||
|
||||
from portail_citoyen2.apps.data_source_plugin.models import DataSource
|
||||
from cmsplugin_blurp.renderers.data_source import Data
|
||||
|
||||
import requests
|
||||
import eopayment
|
||||
|
||||
SERVICES = ((eopayment.SIPS, 'SIPS'),
|
||||
(eopayment.SYSTEMPAY, 'SYSTEMPAY'),
|
||||
(eopayment.SPPLUS, 'SPPLUS'),
|
||||
(eopayment.TIPI, 'TIPI'),
|
||||
(eopayment.DUMMY, 'DUMMY'),
|
||||
)
|
||||
|
||||
TRANSACTION_STATUS_PROD = (
|
||||
('CREATED', 'CREATED'),
|
||||
('PAID', 'PAID'),
|
||||
('DENIED', 'DENIED'),
|
||||
('CANCELED', 'CANCELED'),
|
||||
('ERROR', 'ERROR'),
|
||||
)
|
||||
TRANSACTION_STATUS_TEST = tuple((('TEST_%s' % k, 'TEST_%s' %v)
|
||||
for k,v in TRANSACTION_STATUS_PROD))
|
||||
TRANSACTION_STATUS = TRANSACTION_STATUS_PROD + TRANSACTION_STATUS_TEST
|
||||
|
||||
|
||||
class Regie(models.Model):
|
||||
label = models.CharField(max_length=64)
|
||||
slug = models.SlugField(unique=True)
|
||||
description = models.TextField()
|
||||
service = models.CharField(max_length=64, choices=SERVICES)
|
||||
get_url = models.ForeignKey(DataSource, related_name='regie_get',
|
||||
help_text=_('Get an invoice from this Regie'))
|
||||
update_url = models.ForeignKey(DataSource, related_name='regie_update',
|
||||
help_text=_('Update an invoice of this Regie'))
|
||||
get_list_url = models.ForeignKey(DataSource, related_name='regie_get_list',
|
||||
blank=True, null=True,
|
||||
help_text=_("Get a list of invoices "\
|
||||
"(RequestContext dependent, typically user's invoices)"))
|
||||
|
||||
def natural_key(self):
|
||||
return (self.slug,)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.label
|
||||
|
||||
def get_invoice_list(self, request, **kwargs):
|
||||
if not self.get_list_url:
|
||||
return []
|
||||
context = RequestContext(request, kwargs)
|
||||
data_source = Data(self.get_list_url, context, limit=None, refresh=None)
|
||||
content = data_source.update_content()
|
||||
return content.get('data', {}).get('invoices', [])
|
||||
|
||||
def get_invoice(self, invoice_id, invoice_hash=None, request=None):
|
||||
'''get an invoice (dict), via webservice
|
||||
invoice_hash: a key to access the invoice (for example a password)
|
||||
'''
|
||||
context = {'regie': self,
|
||||
'invoice_id': invoice_id,
|
||||
'invoice_hash': invoice_hash}
|
||||
if request:
|
||||
context = RequestContext(request, context)
|
||||
data_source = Data(self.get_url, context, limit=None, refresh=None)
|
||||
content = data_source.update_content()
|
||||
invoice = content.get('data', {}).get('invoice', {})
|
||||
if invoice:
|
||||
invoice['url'] = reverse('transaction',
|
||||
args=(self.slug, invoice_id, invoice_hash))
|
||||
# is this invoice in the list of invoices ? (typically, list
|
||||
# of user's invoices). If yes, add a "download_url" value
|
||||
if self.get_list_url and request and request.user.is_authenticated():
|
||||
invoice['in_list'] = False
|
||||
ctx_invoices = self.get_invoice_list(request)
|
||||
for i in ctx_invoices:
|
||||
if i['id'] == invoice['id']:
|
||||
invoice['download_url'] = reverse('invoice-download',
|
||||
args=(self.slug, invoice_id, invoice_hash))
|
||||
break
|
||||
return invoice
|
||||
|
||||
|
||||
class Option(models.Model):
|
||||
regie = models.ForeignKey(Regie)
|
||||
name = models.CharField(max_length=32)
|
||||
value = models.CharField(max_length=256)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def __unicode__(self):
|
||||
return _('%s: %s') % (self.name, self.value)
|
||||
|
||||
class ServiceOption(Option):
|
||||
pass
|
||||
|
||||
class RequestOption(Option):
|
||||
pass
|
||||
|
||||
class TransactionEvent(models.Model):
|
||||
regie = models.ForeignKey(Regie)
|
||||
transaction_id = models.CharField(max_length=128, db_index=True)
|
||||
invoice_id= models.CharField(max_length=128, db_index=True)
|
||||
date = models.DateTimeField(auto_now_add=True)
|
||||
address = models.GenericIPAddressField(null=True, blank=True)
|
||||
nameid = models.CharField(max_length=256, null=True, blank=True)
|
||||
status = models.CharField(max_length=16, choices=TRANSACTION_STATUS,
|
||||
default='CREATED')
|
||||
response = models.BooleanField(default=False)
|
||||
details = JSONField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
get_latest_by = 'date'
|
||||
ordering = ['date']
|
||||
verbose_name = _('Transaction event')
|
||||
verbose_name_plural = _('Transaction events')
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
DATETIME;TRANSACTION_ID;INVOICE;STATUS;TIPI_NUMCLI;TIPI_REFDET;TIPI_MONTANT;TIPI_RESULTRANS;TIPI_DATTRANS;TIPI_HEURTRANS;TIPI_SAISIE;TIPI_MEL;TIPI_NUMAUTO{% for e in transactionevent_list %}
|
||||
{{ e.date|date:'c' }};{{ e.transaction_id }};{{ e.invoice_id }};{{ e.status }};{% with bd=e.details.bank_data %}{{ bd.numcli }};{{ bd.refdet }};{{ bd.montant }};{{ bd.resultrans }};{{ bd.dattrans }};{{ bd.heurtrans }};{{ bd.saisie}};{{ bd.mel }};{{ bd.numauto }}{% endwith %}{% endfor %}
|
|
|
@ -0,0 +1,228 @@
|
|||
{% extends 'base-cms.html' %}
|
||||
{% load i18n %}
|
||||
{% load orleans_tags %}
|
||||
{% load facturier_tags %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="/factures/">Mes factures</a></li>
|
||||
<li class="separ"> / </li>
|
||||
<li class="last">Détails de la facture n°{{ invoice.id }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
|
||||
{% if perms.facturier %}
|
||||
<p>
|
||||
<em>Les informations ci-dessous sont visibles car vous avec
|
||||
les droits "staff" sur l'application. Un utilisateur habituel
|
||||
ne verra rien.</em>
|
||||
</p>
|
||||
|
||||
<div class="blocProgram">
|
||||
<h2 class="title">Mode test</h2>
|
||||
<div class="rteContent">
|
||||
<p>
|
||||
En tant qu'utilisateur {{ request.user }} vous pouvez lancer un faux paiement (test)
|
||||
en cochant cette case :<br /><label><input type="checkbox" name="test" id="test" />
|
||||
<strong>appeler TIPI en mode test</strong></label>
|
||||
</p>
|
||||
</div>
|
||||
{% if user.is_superuser %}
|
||||
<h2 class="title">Infos techniques</h2>
|
||||
<div class="rteContent">
|
||||
<p>
|
||||
{% for k,v in invoice.items %}
|
||||
<strong>{{ k }}</strong>: {{ v }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock sidebar %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>Facture {{ invoice.id }}</h1>
|
||||
<div class="wrapSpecial"><div class="rteContent">
|
||||
|
||||
<h2>Montant : {{ invoice.amount }} €</h2>
|
||||
|
||||
<p>Facture émise le
|
||||
{{ invoice.creation_date|iso8601|date:"l j F Y" }}
|
||||
{% if invoice.prelevement_automatique %}
|
||||
<br />
|
||||
Prélèvement automatique effectué le {{ invoice.expiration_date|iso8601|date:"l j F Y" }}
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
<h2>Détails de la facture</h2>
|
||||
|
||||
<p id="download">
|
||||
{% if invoice.download_url %}
|
||||
<a href="{{ invoice.download_url }}#{{invoice.id}}.pdf"
|
||||
title="facture_{{ invoice.id }}.pdf"
|
||||
download="facture_{{ invoice.id }}.pdf"
|
||||
class="download">Télécharger la version PDF complète de la facture</a>
|
||||
{% else %}
|
||||
{% if user.is_authenticated %}
|
||||
Cette facture ne vous est pas destinée, vous ne pouvez pas en
|
||||
voir les détails, uniquement la payer en ligne.
|
||||
{% else %}
|
||||
Pour voir les détails de cette facture, vous devez vous
|
||||
connecter à votre compte citoyen. Sans être connecté,
|
||||
vous pouvez uniquement la payer en ligne.
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
<h2>Paiement en ligne</h2>
|
||||
|
||||
{% if invoice.prelevement_automatique %}
|
||||
<p>Facture en prélévement automatique, vous ne pouvez pas la payer en ligne.</p>
|
||||
|
||||
{% elif invoice.paid %}
|
||||
<p>
|
||||
Cette facture a déjà été payée
|
||||
{% if invoice.paid_date %}le {{ invoice.paid_date }}{% endif %}
|
||||
</p>
|
||||
|
||||
{% elif invoice.expired %}
|
||||
<p>
|
||||
Cette facture est expirée depuis le
|
||||
{{ invoice.expiration_date|iso8601|date:"l j F Y" }} :
|
||||
vous ne pouvez plus la payer en ligne.
|
||||
</p>
|
||||
|
||||
{% elif invoice.amount|decimal < 1.0 %}
|
||||
<p>
|
||||
Le montant de cette facture est inférieur à 1 € (un euro),
|
||||
vous ne pouvez pas la payer en ligne.
|
||||
</p>
|
||||
<p>
|
||||
Il s'agit d'une contrainte imposée par le système de paiement
|
||||
«TIPI» de la Direction Générale des Finances Publiques.
|
||||
</p>
|
||||
|
||||
{% else %}
|
||||
|
||||
<p>
|
||||
Si vous désirez payer cette facture en ligne, indiquez d'abord votre
|
||||
adresse mail ci-dessous, puis cliquez sur le bouton «payer en ligne».
|
||||
</p>
|
||||
<p>
|
||||
<label>Votre adresse mail :</label>
|
||||
<input type="email" name="email" id="email" placeholder="nom@domaine.fr"
|
||||
{% if request.user.email %}
|
||||
value="{{ request.user.email }}"
|
||||
{% else %}
|
||||
placeholder="nom@domaine.fr"
|
||||
{% endif %}
|
||||
/>
|
||||
<span id="error" style="display: none; color: red;">
|
||||
Adresse mail invalide ! Vous devez indiquer votre adresse mail correcte
|
||||
pour payer.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div id="pay">
|
||||
<p>
|
||||
<button style="font-size: 1.2em;" onclick="tipi()">Payer cette facture en ligne</button>
|
||||
</p>
|
||||
<p>
|
||||
En cliquant sur ce bouton, vous allez être redirigé vers le site TIPI
|
||||
de la Direction générale des Finances publiques (DGFiP), qui vous permettra de
|
||||
payer cette facture.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Attention : le système de paiement va s'ouvrir dans une fenêtre «popup» :
|
||||
avant de cliquer, veillez à désactiver tout bloqueur de fenêtre publicitaire
|
||||
(système «anti-pop-up»).</strong>
|
||||
</p>
|
||||
</div>
|
||||
<div id="pay-open" style="display: none;">
|
||||
<p>
|
||||
Vous avez cliqué sur le bouton de paiement. Si la fenêtre de paiement
|
||||
n'apparait pas, vérifiez qu'elle n'est pas bloquée par un système
|
||||
«anti-publicité» ou tout autre système «anti-pop-up».
|
||||
</p>
|
||||
</div>
|
||||
<div id="pay-close" style="display: none;">
|
||||
<p>
|
||||
Vous venez de fermer la fenêtre du paiement.
|
||||
La ville est désormais en attente de
|
||||
validation du paiement de la part de la DGFiP.
|
||||
</p>
|
||||
<p>
|
||||
Note : si vous n'avez pas réussi à effectuer le paiement ou si vous avez
|
||||
fermé la fenêtre avant de le terminer, vous pouvez
|
||||
<a href="javascript:tipi()">relancer le paiement</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var popup;
|
||||
var timer;
|
||||
|
||||
var error = document.getElementById('error');
|
||||
var pay = document.getElementById('pay');
|
||||
var pay_open = document.getElementById('pay-open');
|
||||
var pay_close = document.getElementById('pay-close');
|
||||
|
||||
function validateEmail(email) {
|
||||
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
return re.test(email);
|
||||
}
|
||||
|
||||
function tipi() {
|
||||
var email = document.getElementById('email');
|
||||
var test = document.getElementById('test');
|
||||
|
||||
pay_close.style.display='none';
|
||||
|
||||
var url = '{{ invoice.url|safe }}';
|
||||
if (url.indexOf('?') == -1) {
|
||||
url = url + '?';
|
||||
} else {
|
||||
url = url + '&';
|
||||
}
|
||||
|
||||
if (validateEmail(email.value)) {
|
||||
url +='email=' + email.value;
|
||||
error.style.display='none';
|
||||
} else {
|
||||
error.style.display='block';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (test)
|
||||
if (test.checked)
|
||||
url += '&saisie=T';
|
||||
|
||||
pay.innerHTML = '<p><strong>Paiement en cours.</strong></p>';
|
||||
pay_open.style.display='block';
|
||||
|
||||
popup = window.open(url, 'tipi', 'height=800, width=900, toolbar=no, menubar=no, scrollbars=no, resizable=yes, location=no, directories=no, status=no');
|
||||
timer = setInterval(checkChild, 500);
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkChild() {
|
||||
if (popup.closed) {
|
||||
pay_open.style.display='none';
|
||||
pay_close.style.display='block';
|
||||
document.getElementById('pay').innerHTML = '<p><strong>Fenêtre de paiement fermée.</strong></p>';
|
||||
clearInterval(timer);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,59 @@
|
|||
{% extends "base.html" %}
|
||||
{% block breadcrumbs %}
|
||||
<li>Paiement de la facture {{ invoice_id }}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if paid %}
|
||||
|
||||
<h1>Cette facture a déjà été payée !</h1>
|
||||
|
||||
{% if paid_date %}
|
||||
le {{ paid_date.date|date:"d/m/Y" }} à {{ paid_date.date|date:"H:i" }}
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
|
||||
<h1>Attention ! Le paiement de cette facture est peut-être déjà en cours.</h1>
|
||||
|
||||
<div class="wrapSpecial"><div class="rteContent">
|
||||
|
||||
<p>
|
||||
Attention ! Une transaction de paiement pour cette facture {{ invoice_id }}
|
||||
est en cours depuis le {{ last_transaction_date|date:"d/m/Y" }}
|
||||
à {{ last_transaction_date|date:'H:i' }}.
|
||||
</p>
|
||||
|
||||
<script>
|
||||
function force_new() {
|
||||
c = confirm("Êtes-vous vraiment certain-e que cette facture {{invoice_id}} n'a pas déjà été payée, même par une autre personne ?\nSi vous avez un doute, nous vous conseillons d'annuler et d'attendre deux jours : après ce délai la ville aura été informée d'un paiement. Vous pourrez alors voir si la facture a vraiment été payée ou non.\n");
|
||||
if (c == false) {
|
||||
window.close();
|
||||
};
|
||||
return c;
|
||||
}
|
||||
</script>
|
||||
<p>
|
||||
{% if force_new_transaction_allowed %}
|
||||
Si vous aviez abandonné un paiement précédent,
|
||||
si vous êtes sûr-e que cette facture n'a pas été payée,
|
||||
vous pouvez relancer le paiement en cliquant ici :
|
||||
<a href="{% url "transaction" slug invoice_id invoice_hash %}?force&{{ request.GET.urlencode }}"
|
||||
onclick="return force_new();">
|
||||
lancer une nouvelle demande de paiement
|
||||
</a>.
|
||||
<br/>
|
||||
<strong>Attention, ne cliquez que si vous êtes sûr-e que
|
||||
la transaction précédente n'a pas fonctionné et a bien été
|
||||
abandonnée, et si vous êtes certain-e que le paiement de
|
||||
la facture {{invoice_id}} n'a pas été fait par quelqu'un
|
||||
d'autre.</strong>
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
</div></div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock content %}
|
|
@ -0,0 +1,9 @@
|
|||
from django import template
|
||||
from decimal import Decimal
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.filter
|
||||
def decimal(value):
|
||||
return Decimal(value)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
def payment_url(invoice_id, invoice_hash):
|
||||
return reverse('transaction', args=('tipi', invoice_id, invoice_hash))
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
from django.conf.urls import patterns, include, url
|
||||
from .views import InvoiceView, InvoiceDownloadView, TransactionView, TransactionResponseListView
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^simple/(?P<slug>\w+)/(?P<id>\w+)/(?P<hash>\w+)$',
|
||||
InvoiceView.as_view(),
|
||||
name='invoice'),
|
||||
url(r'^details/(?P<slug>\w+)/(?P<id>\w+)/(?P<hash>\w+)$',
|
||||
InvoiceDownloadView.as_view(),
|
||||
name='invoice-download'),
|
||||
url(r'^transaction/(?P<slug>\w+)/(?P<id>\w+)/(?P<hash>\w+)$',
|
||||
TransactionView.as_view(),
|
||||
name='transaction'),
|
||||
url(r'^responses/(?P<regie>\w+).(?P<days>\d+).csv$',
|
||||
TransactionResponseListView.as_view(),
|
||||
name='responses'),
|
||||
)
|
|
@ -0,0 +1,278 @@
|
|||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.http import HttpResponse, HttpResponseForbidden
|
||||
from django.template import RequestContext
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.shortcuts import redirect
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
from . import app_settings
|
||||
|
||||
import datetime
|
||||
import eopayment
|
||||
|
||||
from .models import Regie, TransactionEvent
|
||||
from portail_citoyen.apps.data_source_plugin.cms_plugins import Data
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LoginRequiredMixin(object):
|
||||
@classmethod
|
||||
def as_view(cls, **initkwargs):
|
||||
view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
|
||||
return login_required(view)
|
||||
|
||||
|
||||
class InvoiceView(DetailView):
|
||||
model = Regie
|
||||
http_method_names = [u'get']
|
||||
|
||||
def get_template_names(self):
|
||||
return ('facturier/%s.html' % self.object.slug,
|
||||
'facturier/%s.html' % self.object.service)
|
||||
|
||||
def get_object_and_invoice(self, **kwargs):
|
||||
self.object = self.get_object()
|
||||
self.invoice = self.object.get_invoice(kwargs['id'],
|
||||
kwargs['hash'], self.request)
|
||||
|
||||
def get_context_data(self):
|
||||
context = super(InvoiceView, self).get_context_data()
|
||||
context['invoice'] = self.invoice
|
||||
return context
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.get_object_and_invoice(**kwargs)
|
||||
context = self.get_context_data()
|
||||
return self.render_to_response(context)
|
||||
|
||||
|
||||
class InvoiceDownloadView(LoginRequiredMixin, InvoiceView):
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.get_object_and_invoice(**kwargs)
|
||||
# if invoice can't be downloaded, stop here
|
||||
if not self.invoice.get('download_url'):
|
||||
return HttpResponseForbidden()
|
||||
context = self.get_context_data()
|
||||
filename = app_settings.download_filename.format(**context)
|
||||
mimetype = app_settings.download_filename_mimetype
|
||||
return HttpResponse(open(filename, 'rb'), mimetype=mimetype)
|
||||
|
||||
|
||||
class TransactionView(DetailView):
|
||||
model = Regie
|
||||
template_name = 'facturier/transaction.html'
|
||||
http_method_names = [u'get', u'post']
|
||||
|
||||
def create_event(self, transaction_id, invoice_id, status,
|
||||
response=False, message=None, details={}):
|
||||
address=self.request.META.get('HTTP_X_REAL_IP') or \
|
||||
self.request.META.get('HTTP_X_FORWARDED_FOR') or \
|
||||
self.request.META.get('REMOTE_ADDR')
|
||||
details['message'] = message
|
||||
TransactionEvent.objects.create(invoice_id=invoice_id,
|
||||
regie=self.object,
|
||||
transaction_id=transaction_id,
|
||||
address=address,
|
||||
response=response,
|
||||
status=status,
|
||||
details=details)
|
||||
|
||||
def create_transaction(self, options, invoice, context, message=None):
|
||||
p = eopayment.Payment(kind=self.object.service,
|
||||
options=options)
|
||||
transaction_id, kind, redirect_url = p.request(**invoice)
|
||||
assert kind == eopayment.URL
|
||||
self.create_event(transaction_id, context['invoice_id'], 'CREATED',
|
||||
message=message)
|
||||
return transaction_id, redirect_url
|
||||
|
||||
def handle_transaction(self, invoice, context):
|
||||
"""
|
||||
checks if a transaction exists, otherwise creates a new transaction.
|
||||
"""
|
||||
service_options = dict([(option.name, option.value) \
|
||||
for option in self.object.serviceoption_set.all()])
|
||||
try:
|
||||
event = TransactionEvent.objects.filter(regie=self.object,
|
||||
invoice_id=context['invoice_id']).latest()
|
||||
except ObjectDoesNotExist:
|
||||
# this is a new invoice : create a new transaction
|
||||
transaction_id, redirect_url = self.create_transaction(service_options,
|
||||
invoice, context, message='new')
|
||||
context.update({'redirect_url': redirect_url})
|
||||
else:
|
||||
if event.status == 'PAID':
|
||||
# a online payment took place = the user can't pay again
|
||||
context['paid'] = True
|
||||
context['paid_date'] = event.date
|
||||
elif event.status == 'CREATED' and 'force' in self.request.GET:
|
||||
# the user want to force a new transaction : cancel the current
|
||||
# one and create a new one
|
||||
self.create_event(event.transaction_id, context['invoice_id'],
|
||||
status='CANCELED',
|
||||
message='forced by user')
|
||||
transaction_id, redirect_url = self.create_transaction(service_options,
|
||||
invoice, context,
|
||||
message='forced by user, replace %s' % event.transaction_id)
|
||||
context.update({'redirect_url': redirect_url})
|
||||
elif event.status == 'CREATED':
|
||||
# there is a current transaction: propose to "force" a new transaction
|
||||
context['force_new_transaction_allowed'] = True
|
||||
context['last_transaction_date'] = event.date
|
||||
else:
|
||||
# the last transaction is closed (cancel, error, test, etc.):
|
||||
# create a new one
|
||||
transaction_id, redirect_url = self.create_transaction(service_options,
|
||||
invoice, context,
|
||||
message='recreated after %s of %s' % (event.status, event.transaction_id))
|
||||
context.update({'redirect_url': redirect_url})
|
||||
|
||||
return context
|
||||
|
||||
def invoice_rest_request(self, data_source_url, context):
|
||||
data = Data(data_source_url, RequestContext(self.request, context),
|
||||
limit=None, refresh=None)
|
||||
return data.update_content().get('data').get('invoice')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(TransactionView, self).get_context_data(**kwargs)
|
||||
invoice_id = self.kwargs['id']
|
||||
invoice_hash = self.kwargs['hash']
|
||||
slug = self.object.slug # (self.object is a "Regie")
|
||||
|
||||
# create an invoice :
|
||||
# 1. create a base from request and regie options
|
||||
invoice = {}
|
||||
if hasattr(self.request.user, 'email'):
|
||||
invoice['email'] = self.request.user.email
|
||||
request_options = dict([(option.name, option.value) \
|
||||
for option in self.object.requestoption_set.all()])
|
||||
invoice.update(request_options)
|
||||
|
||||
# get invoice from the regie (webservice)
|
||||
context.update({'invoice_id': invoice_id,
|
||||
'invoice_hash': invoice_hash,
|
||||
'slug': slug,
|
||||
'paid': False,})
|
||||
invoice_data = self.invoice_rest_request(self.object.get_url, context)
|
||||
invoice.update(invoice_data)
|
||||
|
||||
# invoice can be overriden by request.GET parameters
|
||||
if self.request.GET:
|
||||
for k, v in self.request.GET.iteritems():
|
||||
if k in invoice:
|
||||
invoice[k] = v
|
||||
|
||||
# invoice is paid : stop now
|
||||
if invoice.get('paid'):
|
||||
context['paid'] = True
|
||||
return context
|
||||
|
||||
next_url = reverse('transaction', args=(slug, invoice_id, invoice_hash))
|
||||
if request_options.get('next_url_base'):
|
||||
invoice['next_url'] = str('%s%s' % (request_options['next_url_base'] ,next_url))
|
||||
else:
|
||||
invoice['next_url'] = self.request.build_absolute_uri(next_url)
|
||||
context.update({'details': invoice})
|
||||
|
||||
self.handle_transaction(invoice, context)
|
||||
logger.debug('payment request: context %s' % context)
|
||||
return context
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
context = self.get_context_data(object=self.object)
|
||||
if context.get('redirect_url'):
|
||||
return redirect(context['redirect_url'], permanent=False)
|
||||
return self.render_to_response(context)
|
||||
|
||||
# don't use CSRF protection (for post)
|
||||
@csrf_exempt
|
||||
def dispatch(self, *args, **kwargs):
|
||||
return super(TransactionView, self).dispatch(*args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
logger.debug('payment response: path %s' % request.path)
|
||||
|
||||
query_string = str(request.META['QUERY_STRING'])
|
||||
if not query_string:
|
||||
if request.META['CONTENT_TYPE'] == 'application/x-www-form-urlencoded':
|
||||
query_string = str(request.body)
|
||||
logger.debug('payment response: query_string %s', query_string)
|
||||
|
||||
self.object = self.get_object()
|
||||
service_options = dict([(option.name, option.value) \
|
||||
for option in self.object.serviceoption_set.all()])
|
||||
|
||||
invoice_id = self.kwargs['id']
|
||||
invoice_hash = self.kwargs['hash']
|
||||
logger.debug('payment response: invoice %s', invoice_id)
|
||||
|
||||
try:
|
||||
event = TransactionEvent.objects.filter(regie=self.object,
|
||||
invoice_id=invoice_id).latest()
|
||||
logger.debug('payment response: found transaction %s', event.transaction_id)
|
||||
except ObjectDoesNotExist:
|
||||
logger.warn('payment response: no transaction for invoice %s', invoice_id)
|
||||
return HttpResponse(status=404) # HTTP Not Found
|
||||
if event.status != 'CREATED':
|
||||
logger.warn('payment response: transaction status != CREATED')
|
||||
return HttpResponse(status=410) # HTTP Gone
|
||||
|
||||
backend = eopayment.Payment(kind=self.object.service, options=service_options)
|
||||
response = backend.response(query_string)
|
||||
logger.debug('payment response: response %s', response)
|
||||
|
||||
if response.result == eopayment.common.PAID:
|
||||
status = 'PAID'
|
||||
else:
|
||||
status = 'ERROR'
|
||||
if response.test:
|
||||
status = 'TEST_%s' % status
|
||||
context = {
|
||||
'invoice_id': invoice_id,
|
||||
'invoice_hash': invoice_hash,
|
||||
'status': status
|
||||
}
|
||||
|
||||
logger.debug('payment response: close transaction %s' % event.transaction_id)
|
||||
self.create_event(event.transaction_id, invoice_id, status,
|
||||
response=True, message='response', details=response.__dict__)
|
||||
logger.debug('payment response: update invoice PAID %s -- context %s' %
|
||||
(self.object.update_url, context))
|
||||
self.invoice_rest_request(self.object.update_url, context)
|
||||
|
||||
# ok !
|
||||
logger.debug('payment response: OK invoice %s', invoice_id)
|
||||
return HttpResponse(status=200)
|
||||
|
||||
|
||||
class TransactionResponseListView(ListView):
|
||||
content_type = 'text/csv'
|
||||
|
||||
def get_regie(self):
|
||||
self.regie = Regie.objects.filter(slug=self.kwargs['regie']).get()
|
||||
|
||||
def get_template_names(self):
|
||||
return ('facturier/response-%s.csv' % self.regie.slug,
|
||||
'facturier/response-%s.csv' % self.regie.service)
|
||||
|
||||
def get_queryset(self):
|
||||
days = int(self.kwargs.get('days', 5))
|
||||
day_start = datetime.datetime.now() - datetime.timedelta(days)
|
||||
return TransactionEvent.objects.filter(regie=self.regie,
|
||||
response=True,
|
||||
date__gte=day_start)
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if request.GET.get('key') != app_settings.responses_csv_key:
|
||||
return HttpResponseForbidden('forbidden')
|
||||
self.get_regie()
|
||||
return super(TransactionResponseListView, self).\
|
||||
get(request, *args, **kwargs)
|
||||
|
Reference in New Issue