auquo-payment-cancel.diff
| payments.py (copie de travail) | ||
|---|---|---|
|
from decimal import Decimal
|
||
|
from quixote import redirect, get_request, get_session
|
||
|
from quixote import redirect, get_publisher, get_request, get_session
|
||
|
from quixote.directory import Directory
|
||
|
if not set:
|
||
| ... | ... | |
|
class Invoice(StorableObject):
|
||
|
_names = 'invoices'
|
||
|
_hashed_indexes = ['user_id', 'regie_id']
|
||
|
_hashed_indexes = ['user_id', 'user_hash', 'regie_id']
|
||
|
user_id = None
|
||
|
user_hash = None
|
||
|
regie_id = None
|
||
|
formdef_id = None
|
||
|
formdata_id = None
|
||
| ... | ... | |
|
date = None
|
||
|
paid = False
|
||
|
paid_date = None
|
||
|
canceled = False
|
||
|
canceled_date = None
|
||
|
canceled_reason = None
|
||
|
next_status = None
|
||
|
def __init__(self, id=None, regie_id=None, formdef_id=None):
|
||
| ... | ... | |
|
return False
|
||
|
check_crc = classmethod(check_crc)
|
||
|
def cancel(self, reason=None):
|
||
|
self.canceled = True
|
||
|
self.canceled_date = dt.now()
|
||
|
if reason:
|
||
|
self.canceled_reason = reason
|
||
|
self.store()
|
||
|
INVOICE_EVO_VIEW = {
|
||
|
'create': N_('Create Invoice <a href="%(url)s">%(id)s</a>: %(subject)s - %(amount)s €'),
|
||
|
'pay': N_('Invoice <a href="%(url)s">%(id)s</a> is paid'),
|
||
|
'cancel': N_('Cancel Invoice <a href="%(url)s">%(id)s</a>'),
|
||
|
}
|
||
|
class InvoiceEvolutionPart:
|
||
|
action = None
|
||
|
id = None
|
||
|
subject = None
|
||
|
amount = None
|
||
|
def __init__(self, action, invoice):
|
||
|
self.action = action
|
||
|
self.id = invoice.id
|
||
|
self.subject = invoice.subject
|
||
|
self.amount = invoice.amount
|
||
|
def view(self):
|
||
|
vars = {
|
||
|
'url': '%s/invoices/%s' % (get_publisher().get_frontoffice_url(), self.id),
|
||
|
'id': self.id,
|
||
|
'subject': self.subject,
|
||
|
'amount': self.amount,
|
||
|
}
|
||
|
return htmltext('<p>' + _(INVOICE_EVO_VIEW[self.action]) % vars + '</p>')
|
||
|
class Transaction(StorableObject):
|
||
|
_names = 'transactions'
|
||
|
_hashed_indexes = ['invoice_ids']
|
||
| ... | ... | |
|
def perform(self, formdata):
|
||
|
invoice = Invoice(regie_id=self.regie_id, formdef_id=formdata.formdef.id)
|
||
|
invoice.user_id = get_request().user.id # FIXME: handle user_hash
|
||
|
invoice.user_id = formdata.user_id
|
||
|
invoice.user_hash = formdata.user_hash
|
||
|
invoice.formdata_id = formdata.id
|
||
|
invoice.next_status = self.next_status
|
||
|
if self.subject:
|
||
| ... | ... | |
|
invoice.amount = self.calculate_amount(formdata)
|
||
|
invoice.date = dt.now()
|
||
|
invoice.store()
|
||
|
# FIXME: add a message in formdata.evolution
|
||
|
# add a message in formdata.evolution
|
||
|
evo = Evolution()
|
||
|
evo.time = time.localtime()
|
||
|
evo.status = formdata.status
|
||
|
evo.add_part(InvoiceEvolutionPart('create', invoice))
|
||
|
if not formdata.evolution:
|
||
|
formdata.evolution = []
|
||
|
formdata.evolution.append(evo)
|
||
|
formdata.store()
|
||
|
# redirect the user to "my invoices"
|
||
|
return get_publisher().get_frontoffice_url() + '/myspace/invoices/'
|
||
|
register_item_class(PaymentWorkflowStatusItem)
|
||
|
class PaymentCancelWorkflowStatusItem(WorkflowStatusItem):
|
||
|
description = N_('Payment Cancel')
|
||
|
key = 'payment-cancel'
|
||
|
endpoint = False
|
||
|
reason = None
|
||
|
regie_id = None
|
||
|
def render_as_line(self):
|
||
|
if self.regie_id:
|
||
|
if self.regie_id == '_all':
|
||
|
return _('Cancel all Payments')
|
||
|
else:
|
||
|
return _('Cancel Payments for %s' % Regie.get(self.regie_id).label)
|
||
|
else:
|
||
|
return _('Cancel Payments (non completed)')
|
||
|
def get_parameters(self):
|
||
|
return ('reason', 'regie_id')
|
||
|
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
|
||
|
if 'reason' in parameters:
|
||
|
form.add(StringWidget, '%sreason' % prefix, title=_('Reason'),
|
||
|
value=self.reason, size=40)
|
||
|
if 'regie_id' in parameters:
|
||
|
form.add(SingleSelectWidget, '%sregie_id' % prefix,
|
||
|
title=_('Regie'), value=self.regie_id,
|
||
|
options = [(None, '---'), ('_all', _('All Regies'))] + \
|
||
|
[(x.id, x.label) for x in Regie.select()])
|
||
|
def perform(self, formdata):
|
||
|
invoices_id = []
|
||
|
# get all invoices for the formdata and the selected regie
|
||
|
for evo in [evo for evo in formdata.evolution if evo.parts]:
|
||
|
for part in [part for part in evo.parts if isinstance(part, InvoiceEvolutionPart)]:
|
||
|
if part.action == 'create':
|
||
|
invoices_id.append(part.id)
|
||
|
elif part.id in invoices_id:
|
||
|
invoices_id.remove(part.id)
|
||
|
invoices = [Invoice.get(id) for id in invoices_id]
|
||
|
# select invoices for the selected regie (if not "all regies")
|
||
|
if self.regie_id != '_all':
|
||
|
invoices = [i for i in invoices if i.regie_id == self.regie_id]
|
||
|
# security filter: check user
|
||
|
invoices = [i for i in invoices if (i.user_id == formdata.user_id) \
|
||
|
or (i.user_hash == formdata.user_hash)]
|
||
|
# security filter: check formdata & formdef
|
||
|
invoices = [i for i in invoices if (i.formdata_id == formdata.id) \
|
||
|
and (i.formdef_id == formdata.formdef.id)]
|
||
|
evo = Evolution()
|
||
|
evo.time = time.localtime()
|
||
|
for invoice in invoices:
|
||
|
if not (invoice.paid or invoice.canceled):
|
||
|
invoice.cancel(self.reason)
|
||
|
evo.add_part(InvoiceEvolutionPart('cancel', invoice))
|
||
|
if not formdata.evolution:
|
||
|
formdata.evolution = []
|
||
|
formdata.evolution.append(evo)
|
||
|
formdata.store()
|
||
|
return get_publisher().get_frontoffice_url() + '/myspace/invoices/'
|
||
|
register_item_class(PaymentCancelWorkflowStatusItem)
|
||
|
def request_payment(invoice_ids, url, add_regie=True):
|
||
|
for invoice_id in invoice_ids:
|
||
|
if not Invoice.check_crc(invoice_id):
|
||
|
raise KeyError()
|
||
|
invoices = [ Invoice.get(invoice_id) for invoice_id in invoice_ids ]
|
||
|
invoices = filter(lambda x: not x.paid, invoices)
|
||
|
invoices = [ i for i in invoices if not (i.paid or i.canceled) ]
|
||
|
regie_ids = set([invoice.regie_id for invoice in invoices])
|
||
|
# Do not apply if more than one regie is used or no invoice is not paid
|
||
|
# Do not apply if more than one regie is used or no invoice is not paid or canceled
|
||
|
if len(invoices) == 0 or len(regie_ids) != 1:
|
||
|
url = get_publisher().get_frontoffice_url()
|
||
|
if get_session().user:
|
||
| payments_ui.ptl (copie de travail) | ||
|---|---|---|
|
'<div class="details">'
|
||
|
htmltext(invoice.details)
|
||
|
'</div>'
|
||
|
if invoice.canceled:
|
||
|
'<p class="canceled">'
|
||
|
'%s' % _('canceled on %s') % misc.localstrftime(invoice.canceled_date)
|
||
|
if invoice.canceled_reason:
|
||
|
' (%s)' % invoice.canceled_reason
|
||
|
'</p>'
|
||
|
if invoice.paid:
|
||
|
'<p class="paid">%s</p>' % _('paid on %s') % misc.localstrftime(invoice.paid_date)
|
||
|
'</div>'
|
||
| ... | ... | |
|
except KeyError:
|
||
|
raise errors.TraversalError()
|
||
|
invoice_as_html(invoice)
|
||
|
if not invoice.paid:
|
||
|
if not (invoice.paid or invoice.canceled):
|
||
|
regies_id.add(invoice.regie_id)
|
||
|
if len(regies_id) == 1:
|
||
| myspace.ptl (copie de travail) | ||
|---|---|---|
|
return Directory._q_traverse(self, path)
|
||
|
def _q_index [html] (self):
|
||
|
user = get_request().user
|
||
|
if not user or user.anonymous:
|
||
|
raise errors.AccessUnauthorizedError()
|
||
|
template.html_top(_('Invoices'))
|
||
|
TextsDirectory.get_html_text('aq-myspace-invoice')
|
||
|
get_session().display_message()
|
||
|
invoices = Invoice.get_with_indexed_value(
|
||
|
str('user_id'), str(get_request().user.id))
|
||
|
invoices = []
|
||
|
invoices.extend(Invoice.get_with_indexed_value(
|
||
|
str('user_id'), str(user.id)))
|
||
|
try:
|
||
|
invoices.extend(Invoice.get_with_indexed_value(
|
||
|
str('user_hash'), str(user.hash)))
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
def cmp_invoice(a, b):
|
||
|
t = cmp(a.regie_id, b.regie_id)
|
||
| ... | ... | |
|
'<ul>'
|
||
|
'<li>'
|
||
|
if not invoice.paid:
|
||
|
if not (invoice.paid or invoice.canceled):
|
||
|
'<input type="checkbox" name="invoice" value="%s"/>' % invoice.id
|
||
|
unpaid = True
|
||
|
misc.localstrftime(invoice.date)
|
||
| ... | ... | |
|
'%s' % invoice.amount
|
||
|
' €'
|
||
|
' - '
|
||
|
button = '<strong>%s</strong>' % _('Pay')
|
||
|
button = '<span class="paybutton">%s</span>' % _('Pay')
|
||
|
if invoice.canceled:
|
||
|
_('canceled on %s') % misc.localstrftime(invoice.canceled_date)
|
||
|
' - '
|
||
|
button = _('Details')
|
||
|
if invoice.paid:
|
||
|
_('paid on %s') % misc.localstrftime(invoice.paid_date)
|
||
|
' - '
|
||