payments: factorize action code (pay, unpay, cancel), add mail notifications

fixes #1718
This commit is contained in:
Benjamin Dauvergne 2013-04-26 11:49:38 +02:00
parent a671160334
commit 90c639436e
4 changed files with 1472 additions and 1501 deletions

View File

@ -149,11 +149,8 @@ def synchronize_domino(publisher):
i, payment_invoice.id)
payment_invoice.remove_self()
elif invoice.paid():
payment_invoice.paid = True
# cannot do better :(
payment_invoice.paid_date = datetime.now()
payment_invoice.paid_by_domino = True
payment_invoice.store()
payment_invoice.pay()
logger.info('domino cron: remote invoice %s has beend paid, '
'local invoice %s of user %s is now marked as paid.',
invoice.id, payment_invoice.id, payment_invoice.user_id)

View File

@ -20,8 +20,8 @@ try:
except ImportError:
pass
from qommon import errors, get_logger, get_cfg, emails
from qommon.storage import StorableObject
from qommon import errors, get_logger, get_cfg
from qommon.form import htmltext, StringWidget, TextWidget, SingleSelectWidget, \
WidgetDict
@ -93,6 +93,7 @@ class Invoice(StorableObject):
def get_new_id(self, create=False):
# format : date-regie-formdef-alea-check
r = random.SystemRandom()
self.fresh = True
while True:
id = '-'.join([
dt.now().strftime('%Y%m%d'),
@ -105,6 +106,12 @@ class Invoice(StorableObject):
if not self.has_key(id):
return id
def store(self, *args, **kwargs):
if getattr(self, 'fresh', None) is True:
del self.fresh
notify_new_invoice(self)
return super(Invoice, self).store(*args, **kwargs)
def check_crc(cls, id):
try:
return int(id[-2:]) == (ord(hashlib.md5(id[:-3]).digest()[0]) % 100)
@ -112,12 +119,31 @@ class Invoice(StorableObject):
return False
check_crc = classmethod(check_crc)
def pay(self):
self.paid = True
self.paid_date = dt.now()
self.store()
get_logger().info(_('invoice %s paid'), self.id)
notify_paid_invoice(self)
def unpay(self):
self.paid = False
self.paid_date = None
self.store()
get_logger().info(_('invoice %s unpaid'), self.id)
def cancel(self, reason=None):
self.canceled = True
self.canceled_date = dt.now()
if reason:
self.canceled_reason = reason
self.store()
notify_canceled_invoice(self)
get_logger().info(_('invoice %s canceled'), self.id)
def payment_url(self):
base_url = get_publisher().get_frontoffice_url()
return '%s/invoices/%s' % (base_url, self.id)
INVOICE_EVO_VIEW = {
@ -252,8 +278,9 @@ class PaymentWorkflowStatusItem(WorkflowStatusItem):
invoice.amount = Decimal(self.compute(self.amount))
invoice.date = dt.now()
invoice.request_kwargs = {}
for key, value in self.request_kwargs.iteritems():
invoice.request_kwargs[key] = self.compute(value)
if self.request_kwargs:
for key, value in self.request_kwargs.iteritems():
invoice.request_kwargs[key] = self.compute(value)
invoice.store()
# add a message in formdata.evolution
evo = Evolution()
@ -465,9 +492,7 @@ class PublicPaymentRegieBackDirectory(Directory):
for invoice_id in transaction.invoice_ids:
# all invoices are now paid
invoice = Invoice.get(invoice_id)
invoice.paid = True
invoice.paid_date = dt.now()
invoice.store()
invoice.pay()
# workflow for each related formdata
if invoice.formdef_id and invoice.formdata_id:
@ -531,3 +556,24 @@ class PublicPaymentDirectory(Directory):
url = get_publisher().get_frontoffice_url() + '/payment/back/'
return request_payment(invoice_ids, url)
def notify_new_invoice(invoice):
notify_invoice(invoice, 'payment-new-invoice-email')
def notify_paid_invoice(invoice):
notify_invoice(invoice, 'payment-invoice-paid-email')
def notify_canceled_invoice(invoice):
notify_invoice(invoice, 'payment-invoice-deleted-email')
def notify_invoice(invoice, template):
user = invoice.get_user()
assert user is not None
regie = Regie.get(id=invoice.regie_id)
emails.custom_ezt_email(template, {
'user': user,
'invoice': invoice,
'regie': regie,
'invoice_url': invoice.payment_url()
}, user.email, fire_and_forget = True)

View File

@ -15,8 +15,10 @@ from wcs.formdef import FormDef
from qommon import errors, misc, template, get_logger
from qommon.form import *
from qommon.strftime import strftime
from qommon.admin.emails import EmailsDirectory
from payments import eopayment, Regie, is_payment_supported, Invoice, Transaction
from payments import (eopayment, Regie, is_payment_supported, Invoice,
Transaction, notify_paid_invoice)
from qommon.admin.texts import TextsDirectory
@ -349,8 +351,8 @@ class RegieDirectory(Directory):
return invoices
def unpay(self, request, invoice):
get_logger().info(_('manually set unpaid invoice %s in regie %s')
% (invoice.id, self.regie.id))
get_logger().info(_('manually set unpaid invoice %(invoice_id)s in regie %(regie)s')
% dict(invoice_id=invoice.id, regie=self.regie.id))
transaction = Transaction()
transaction.invoice_ids = [ invoice.id ]
transaction.order_id = 'Manual action'
@ -361,13 +363,11 @@ class RegieDirectory(Directory):
'by': request.user.get_display_name() + ' (%s)' % request.user.id
}
transaction.store()
invoice.paid = False
invoice.paid_date = None
invoice.store()
invoice.unpay()
def pay(self, request, invoice):
get_logger().info(_('manually set paid invoice %s in regie %s')
% (invoice.id, self.regie.id))
get_logger().info(_('manually set paid invoice %(invoice_id)s in regie %(regie)s')
% dict(invoice_id=invoice.id, regie=self.regie.id))
transaction = Transaction()
transaction.invoice_ids = [ invoice.id ]
transaction.order_id = 'Manual action'
@ -378,9 +378,7 @@ class RegieDirectory(Directory):
'by': request.user.get_display_name() + ' (%s)' % request.user.id
}
transaction.store()
invoice.paid = True
invoice.paid_date = transaction.start
invoice.store()
invoice.pay()
def invoice_listing [html] (self):
request = get_request()
@ -458,7 +456,7 @@ class RegieDirectory(Directory):
if offset + self.PAGINATION < len(invoices):
'<a href="?offset=%d>%s</a> ' % (
max(0, offset-self.PAGINATION), _('Previous'))
class RegiesDirectory(Directory):
_q_exports = ['', 'new']
@ -544,3 +542,30 @@ class PaymentsDirectory(AccessControlled, Directory):
TextsDirectory.register('aq-invoice',
N_('Message on top of an invoice'),
category = N_('Invoices'))
EmailsDirectory.register('payment-new-invoice-email',
N_('New invoice'),
N_('Available variables: user, regie, invoice, invoice_url'),
category = N_('Invoices'),
default_subject = N_('New invoice'),
default_body = N_('''
A new invoice is available at [invoice_url].
'''))
EmailsDirectory.register('payment-invoice-paid-email',
N_('Paid invoice'),
N_('Available variables: user, regie, invoice, invoice_url'),
category = N_('Invoices'),
default_subject = N_('Paid invoice'),
default_body = N_('''
The invoice [invoice_url] has been paid.
'''))
EmailsDirectory.register('payment-invoice-canceled-email',
N_('Canceled invoice'),
N_('Available variables: user, regie, invoice, invoice_url'),
category = N_('Invoices'),
default_subject = N_('Canceled invoice'),
default_body = N_('''
The invoice [invoice.id] has been canceled.
'''))

2861
po/fr.po

File diff suppressed because it is too large Load Diff