payments: factorize action code (pay, unpay, cancel), add mail notifications
fixes #1718
This commit is contained in:
parent
a671160334
commit
90c639436e
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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.
|
||||
'''))
|
||||
|
|
Reference in New Issue