Fixes on payments
This commit is contained in:
parent
7c5eff9a90
commit
a8cad48fed
11
TODO.md
11
TODO.md
|
@ -413,3 +413,14 @@ touch /tmp/somefile
|
||||||
# inherit registers from parent?
|
# inherit registers from parent?
|
||||||
|
|
||||||
# Disable pagination on membership fees (allways one page)
|
# Disable pagination on membership fees (allways one page)
|
||||||
|
|
||||||
|
# datetime metric storage granularity: otherwise innacurate detection of billed metric on order.billed_on
|
||||||
|
|
||||||
|
# Serializers.validation migration to DRF3: grep -r 'attrs, source' *|grep -v '~'
|
||||||
|
serailzer self.instance on create.
|
||||||
|
|
||||||
|
# generate Direct debit q19 on a protected path, or store it on the transaction.proc
|
||||||
|
# regenerate direct debit q19
|
||||||
|
# add transproc.method for regeneration
|
||||||
|
|
||||||
|
# TODO wrapp admin delete: delete proc undo processing on related transactions
|
||||||
|
|
|
@ -14,9 +14,9 @@ from . import settings
|
||||||
|
|
||||||
|
|
||||||
class Account(auth.AbstractBaseUser):
|
class Account(auth.AbstractBaseUser):
|
||||||
# Username max_length determined by LINUX system user lentgh: 32
|
# Username max_length determined by LINUX system user/group lentgh: 32
|
||||||
username = models.CharField(_("username"), max_length=32, unique=True,
|
username = models.CharField(_("username"), max_length=32, unique=True,
|
||||||
help_text=_("Required. 64 characters or fewer. Letters, digits and ./-/_ only."),
|
help_text=_("Required. 32 characters or fewer. Letters, digits and ./-/_ only."),
|
||||||
validators=[
|
validators=[
|
||||||
validators.RegexValidator(r'^[\w.-]+$', _("Enter a valid username."), 'invalid')
|
validators.RegexValidator(r'^[\w.-]+$', _("Enter a valid username."), 'invalid')
|
||||||
])
|
])
|
||||||
|
@ -102,7 +102,7 @@ class Account(auth.AbstractBaseUser):
|
||||||
extra_context.update(context)
|
extra_context.update(context)
|
||||||
with translation.override(self.language):
|
with translation.override(self.language):
|
||||||
send_email_template(
|
send_email_template(
|
||||||
template, extra_context, ('marcay@pangea.org',), email_from=email_from, html=html,
|
template, extra_context, email_to, email_from=email_from, html=html,
|
||||||
attachments=attachments)
|
attachments=attachments)
|
||||||
|
|
||||||
def get_full_name(self):
|
def get_full_name(self):
|
||||||
|
|
|
@ -76,8 +76,8 @@ def close_bills(modeladmin, request, queryset):
|
||||||
if num == 1:
|
if num == 1:
|
||||||
url = change_url(transactions[0])
|
url = change_url(transactions[0])
|
||||||
else:
|
else:
|
||||||
url = reverse('admin:transactions_transaction_changelist')
|
url = reverse('admin:payments_transaction_changelist')
|
||||||
url += 'id__in=%s' % ','.join(map(str, transactions))
|
url += 'id__in=%s' % ','.join([str(t.id) for t in transactions])
|
||||||
context = {
|
context = {
|
||||||
'url': url,
|
'url': url,
|
||||||
'num': num,
|
'num': num,
|
||||||
|
@ -109,19 +109,15 @@ close_bills.url_name = 'close'
|
||||||
|
|
||||||
|
|
||||||
def send_bills(modeladmin, request, queryset):
|
def send_bills(modeladmin, request, queryset):
|
||||||
num = 0
|
|
||||||
for bill in queryset:
|
for bill in queryset:
|
||||||
if not validate_contact(request, bill):
|
if not validate_contact(request, bill):
|
||||||
return
|
return
|
||||||
num += 1
|
num = 0
|
||||||
if num == 1:
|
|
||||||
bill.send()
|
|
||||||
else:
|
|
||||||
# Batch email
|
|
||||||
queryset.send()
|
|
||||||
for bill in queryset:
|
for bill in queryset:
|
||||||
|
bill.send()
|
||||||
modeladmin.log_change(request, bill, 'Sent')
|
modeladmin.log_change(request, bill, 'Sent')
|
||||||
messages.success(request, ungetetx(
|
num += 1
|
||||||
|
messages.success(request, ungettext(
|
||||||
_("One bill has been sent."),
|
_("One bill has been sent."),
|
||||||
_("%i bills have been sent.") % num,
|
_("%i bills have been sent.") % num,
|
||||||
num))
|
num))
|
||||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2015-05-28 09:23+0000\n"
|
"POT-Creation-Date: 2015-05-29 09:39+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -28,61 +28,63 @@ msgstr "Vista"
|
||||||
|
|
||||||
#: actions.py:55
|
#: actions.py:55
|
||||||
msgid "Selected bills should be in open state"
|
msgid "Selected bills should be in open state"
|
||||||
msgstr ""
|
msgstr "Les factures seleccionades han d'estar en estat obert"
|
||||||
|
|
||||||
#: actions.py:73
|
#: actions.py:73
|
||||||
msgid "Selected bills have been closed"
|
msgid "Selected bills have been closed"
|
||||||
msgstr ""
|
msgstr "Les factures seleccionades han estat tancades"
|
||||||
|
|
||||||
#: actions.py:86
|
#: actions.py:86
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "<a href=\"%(url)s\">One related transaction</a> has been created"
|
msgid "<a href=\"%(url)s\">One related transaction</a> has been created"
|
||||||
msgstr ""
|
msgstr "S'ha creat una <a href=\"%(url)s\">transacció</a>"
|
||||||
|
|
||||||
#: actions.py:87
|
#: actions.py:87
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "<a href=\"%(url)s\">%(num)i related transactions</a> have been created"
|
msgid "<a href=\"%(url)s\">%(num)i related transactions</a> have been created"
|
||||||
msgstr ""
|
msgstr "S'han creat les <a href=\"%(url)s\">%(num)i següents transaccions</a>"
|
||||||
|
|
||||||
#: actions.py:93
|
#: actions.py:93
|
||||||
msgid "Are you sure about closing the following bills?"
|
msgid "Are you sure about closing the following bills?"
|
||||||
msgstr ""
|
msgstr "Estàs a punt de tancar les següents factures, estàs segur?"
|
||||||
|
|
||||||
#: actions.py:94
|
#: actions.py:94
|
||||||
msgid ""
|
msgid ""
|
||||||
"Once a bill is closed it can not be further modified.</p><p>Please select a "
|
"Once a bill is closed it can not be further modified.</p><p>Please select a "
|
||||||
"payment source for the selected bills"
|
"payment source for the selected bills"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Una vegada la factura estigui tancada no podrà ser modificada.</p><p>Si us "
|
||||||
|
"plau selecciona un mètode de pagament per les factures seleccionades"
|
||||||
|
|
||||||
#: actions.py:107
|
#: actions.py:107
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr ""
|
msgstr "Tanca"
|
||||||
|
|
||||||
#: actions.py:125
|
#: actions.py:125
|
||||||
msgid "One bill has been sent."
|
msgid "One bill has been sent."
|
||||||
msgstr ""
|
msgstr "S'ha creat una factura"
|
||||||
|
|
||||||
#: actions.py:126
|
#: actions.py:126
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%i bills have been sent."
|
msgid "%i bills have been sent."
|
||||||
msgstr ""
|
msgstr "S'han enviat %i factures."
|
||||||
|
|
||||||
#: actions.py:128
|
#: actions.py:128
|
||||||
msgid "Resend"
|
msgid "Resend"
|
||||||
msgstr ""
|
msgstr "Reenviat"
|
||||||
|
|
||||||
#: actions.py:189
|
#: actions.py:189
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(norders)s orders and %(nlines)s lines undoed."
|
msgid "%(norders)s orders and %(nlines)s lines undoed."
|
||||||
msgstr ""
|
msgstr "%(norders)s ordres i %(nlines)s línies desfetes."
|
||||||
|
|
||||||
#: actions.py:208
|
#: actions.py:208
|
||||||
msgid "Lines moved"
|
msgid "Lines moved"
|
||||||
msgstr ""
|
msgstr "Línies mogudes"
|
||||||
|
|
||||||
#: admin.py:49 admin.py:93 admin.py:128 forms.py:11
|
#: admin.py:49 admin.py:93 admin.py:128 forms.py:11
|
||||||
msgid "Total"
|
msgid "Total"
|
||||||
msgstr ""
|
msgstr "Total"
|
||||||
|
|
||||||
#: admin.py:80
|
#: admin.py:80
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
|
@ -90,52 +92,52 @@ msgstr "Descripció"
|
||||||
|
|
||||||
#: admin.py:88
|
#: admin.py:88
|
||||||
msgid "Subtotal"
|
msgid "Subtotal"
|
||||||
msgstr ""
|
msgstr "Subtotal"
|
||||||
|
|
||||||
#: admin.py:118
|
#: admin.py:118
|
||||||
msgid "Is open"
|
msgid "Is open"
|
||||||
msgstr ""
|
msgstr "És oberta"
|
||||||
|
|
||||||
#: admin.py:123
|
#: admin.py:123
|
||||||
msgid "Subline"
|
msgid "Subline"
|
||||||
msgstr ""
|
msgstr "Sublínia"
|
||||||
|
|
||||||
#: admin.py:157
|
#: admin.py:157
|
||||||
msgid "No bills selected."
|
msgid "No bills selected."
|
||||||
msgstr ""
|
msgstr "No hi ha factures seleccionades"
|
||||||
|
|
||||||
#: admin.py:164
|
#: admin.py:164
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Manage %s bill lines."
|
msgid "Manage %s bill lines."
|
||||||
msgstr ""
|
msgstr "Gestiona %s línies de factura."
|
||||||
|
|
||||||
#: admin.py:166
|
#: admin.py:166
|
||||||
msgid "Bill not in open state."
|
msgid "Bill not in open state."
|
||||||
msgstr ""
|
msgstr "La factura no està en estat obert"
|
||||||
|
|
||||||
#: admin.py:169
|
#: admin.py:169
|
||||||
msgid "Not all bills are in open state."
|
msgid "Not all bills are in open state."
|
||||||
msgstr ""
|
msgstr "No totes les factures estan en estat obert"
|
||||||
|
|
||||||
#: admin.py:170
|
#: admin.py:170
|
||||||
msgid "Manage bill lines of multiple bills."
|
msgid "Manage bill lines of multiple bills."
|
||||||
msgstr ""
|
msgstr "Gestiona línies de factura de multiples factures."
|
||||||
|
|
||||||
#: admin.py:190
|
#: admin.py:190
|
||||||
msgid "Raw"
|
msgid "Raw"
|
||||||
msgstr ""
|
msgstr "Raw"
|
||||||
|
|
||||||
#: admin.py:208
|
#: admin.py:208
|
||||||
msgid "Created"
|
msgid "Created"
|
||||||
msgstr ""
|
msgstr "Creada"
|
||||||
|
|
||||||
#: admin.py:213
|
#: admin.py:213
|
||||||
msgid "lines"
|
msgid "lines"
|
||||||
msgstr ""
|
msgstr "línies"
|
||||||
|
|
||||||
#: admin.py:218 templates/bills/microspective.html:118
|
#: admin.py:218 templates/bills/microspective.html:118
|
||||||
msgid "total"
|
msgid "total"
|
||||||
msgstr ""
|
msgstr "total"
|
||||||
|
|
||||||
#: admin.py:226 models.py:88 models.py:352
|
#: admin.py:226 models.py:88 models.py:352
|
||||||
msgid "type"
|
msgid "type"
|
||||||
|
@ -167,11 +169,11 @@ msgstr "Rectificació de quota de soci"
|
||||||
|
|
||||||
#: filters.py:22
|
#: filters.py:22
|
||||||
msgid "Pro-forma"
|
msgid "Pro-forma"
|
||||||
msgstr ""
|
msgstr "Pro-forma"
|
||||||
|
|
||||||
#: filters.py:41
|
#: filters.py:41
|
||||||
msgid "positive price"
|
msgid "positive price"
|
||||||
msgstr ""
|
msgstr "preu positiu"
|
||||||
|
|
||||||
#: filters.py:46 filters.py:64
|
#: filters.py:46 filters.py:64
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
|
@ -183,69 +185,71 @@ msgstr "No"
|
||||||
|
|
||||||
#: filters.py:59
|
#: filters.py:59
|
||||||
msgid "has bill contact"
|
msgid "has bill contact"
|
||||||
msgstr ""
|
msgstr "té contacte de facturació"
|
||||||
|
|
||||||
#: forms.py:9
|
#: forms.py:9
|
||||||
msgid "Number"
|
msgid "Number"
|
||||||
msgstr ""
|
msgstr "Número"
|
||||||
|
|
||||||
#: forms.py:10
|
#: forms.py:10
|
||||||
msgid "Account"
|
msgid "Account"
|
||||||
msgstr ""
|
msgstr "Compte"
|
||||||
|
|
||||||
#: forms.py:12
|
#: forms.py:12
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr ""
|
msgstr "Tipus"
|
||||||
|
|
||||||
#: forms.py:13
|
#: forms.py:13
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr ""
|
msgstr "Font"
|
||||||
|
|
||||||
#: helpers.py:10
|
#: helpers.py:10
|
||||||
msgid ""
|
msgid ""
|
||||||
"{relation} account \"{account}\" does not have a declared invoice contact. "
|
"{relation} account \"{account}\" does not have a declared invoice contact. "
|
||||||
"You should <a href=\"{url}#invoicecontact-group\">provide one</a>"
|
"You should <a href=\"{url}#invoicecontact-group\">provide one</a>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"{relation} compte \"{account}\" no te un contacte de facturació. Hauries de "
|
||||||
|
"<a href=\"{url}#invoicecontact-group\">proporcionar un</a>"
|
||||||
|
|
||||||
#: helpers.py:17
|
#: helpers.py:17
|
||||||
msgid "Related"
|
msgid "Related"
|
||||||
msgstr ""
|
msgstr "Relacionat"
|
||||||
|
|
||||||
#: helpers.py:24
|
#: helpers.py:24
|
||||||
msgid "Main"
|
msgid "Main"
|
||||||
msgstr ""
|
msgstr "Principal"
|
||||||
|
|
||||||
#: models.py:23 models.py:86
|
#: models.py:23 models.py:86
|
||||||
msgid "account"
|
msgid "account"
|
||||||
msgstr ""
|
msgstr "compte"
|
||||||
|
|
||||||
#: models.py:25
|
#: models.py:25
|
||||||
msgid "name"
|
msgid "name"
|
||||||
msgstr ""
|
msgstr "nom"
|
||||||
|
|
||||||
#: models.py:26
|
#: models.py:26
|
||||||
msgid "Account full name will be used when left blank."
|
msgid "Account full name will be used when left blank."
|
||||||
msgstr ""
|
msgstr "S'emprarà el nom complet del compte quan es deixi en blanc."
|
||||||
|
|
||||||
#: models.py:27
|
#: models.py:27
|
||||||
msgid "address"
|
msgid "address"
|
||||||
msgstr ""
|
msgstr "adreça"
|
||||||
|
|
||||||
#: models.py:28
|
#: models.py:28
|
||||||
msgid "city"
|
msgid "city"
|
||||||
msgstr ""
|
msgstr "ciutat"
|
||||||
|
|
||||||
#: models.py:30
|
#: models.py:30
|
||||||
msgid "zip code"
|
msgid "zip code"
|
||||||
msgstr ""
|
msgstr "codi postal"
|
||||||
|
|
||||||
#: models.py:31
|
#: models.py:31
|
||||||
msgid "Enter a valid zipcode."
|
msgid "Enter a valid zipcode."
|
||||||
msgstr ""
|
msgstr "Introdueix un codi postal vàlid."
|
||||||
|
|
||||||
#: models.py:32
|
#: models.py:32
|
||||||
msgid "country"
|
msgid "country"
|
||||||
msgstr ""
|
msgstr "país"
|
||||||
|
|
||||||
#: models.py:35
|
#: models.py:35
|
||||||
msgid "VAT number"
|
msgid "VAT number"
|
||||||
|
@ -253,51 +257,51 @@ msgstr "NIF"
|
||||||
|
|
||||||
#: models.py:67
|
#: models.py:67
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr ""
|
msgstr "Pagat"
|
||||||
|
|
||||||
#: models.py:68
|
#: models.py:68
|
||||||
msgid "Pending"
|
msgid "Pending"
|
||||||
msgstr ""
|
msgstr "Pendent"
|
||||||
|
|
||||||
#: models.py:69
|
#: models.py:69
|
||||||
msgid "Bad debt"
|
msgid "Bad debt"
|
||||||
msgstr ""
|
msgstr "Incobrable"
|
||||||
|
|
||||||
#: models.py:81
|
#: models.py:81
|
||||||
msgid "Amendment Fee"
|
msgid "Amendment Fee"
|
||||||
msgstr ""
|
msgstr "Rectificació de quota de soci"
|
||||||
|
|
||||||
#: models.py:82
|
#: models.py:82
|
||||||
msgid "Pro forma"
|
msgid "Pro forma"
|
||||||
msgstr ""
|
msgstr "Pro forma"
|
||||||
|
|
||||||
#: models.py:85
|
#: models.py:85
|
||||||
msgid "number"
|
msgid "number"
|
||||||
msgstr ""
|
msgstr "número"
|
||||||
|
|
||||||
#: models.py:89
|
#: models.py:89
|
||||||
msgid "created on"
|
msgid "created on"
|
||||||
msgstr ""
|
msgstr "creat el"
|
||||||
|
|
||||||
#: models.py:90
|
#: models.py:90
|
||||||
msgid "closed on"
|
msgid "closed on"
|
||||||
msgstr ""
|
msgstr "tancat el"
|
||||||
|
|
||||||
#: models.py:91
|
#: models.py:91
|
||||||
msgid "open"
|
msgid "open"
|
||||||
msgstr ""
|
msgstr "obert"
|
||||||
|
|
||||||
#: models.py:92
|
#: models.py:92
|
||||||
msgid "sent"
|
msgid "sent"
|
||||||
msgstr ""
|
msgstr "enviat"
|
||||||
|
|
||||||
#: models.py:93
|
#: models.py:93
|
||||||
msgid "due on"
|
msgid "due on"
|
||||||
msgstr ""
|
msgstr "es deu"
|
||||||
|
|
||||||
#: models.py:94
|
#: models.py:94
|
||||||
msgid "updated on"
|
msgid "updated on"
|
||||||
msgstr ""
|
msgstr "actualitzada el"
|
||||||
|
|
||||||
#: models.py:97
|
#: models.py:97
|
||||||
msgid "comments"
|
msgid "comments"
|
||||||
|
@ -305,11 +309,11 @@ msgstr "comentaris"
|
||||||
|
|
||||||
#: models.py:98
|
#: models.py:98
|
||||||
msgid "HTML"
|
msgid "HTML"
|
||||||
msgstr ""
|
msgstr "HTML"
|
||||||
|
|
||||||
#: models.py:285
|
#: models.py:285
|
||||||
msgid "bill"
|
msgid "bill"
|
||||||
msgstr ""
|
msgstr "factura"
|
||||||
|
|
||||||
#: models.py:286 models.py:350 templates/bills/microspective.html:73
|
#: models.py:286 models.py:350 templates/bills/microspective.html:73
|
||||||
msgid "description"
|
msgid "description"
|
||||||
|
@ -332,7 +336,7 @@ msgstr "quantitat"
|
||||||
#: models.py:290 templates/bills/microspective.html:77
|
#: models.py:290 templates/bills/microspective.html:77
|
||||||
#: templates/bills/microspective.html:111
|
#: templates/bills/microspective.html:111
|
||||||
msgid "subtotal"
|
msgid "subtotal"
|
||||||
msgstr ""
|
msgstr "subtotal"
|
||||||
|
|
||||||
#: models.py:291
|
#: models.py:291
|
||||||
msgid "tax"
|
msgid "tax"
|
||||||
|
@ -340,67 +344,69 @@ msgstr "impostos"
|
||||||
|
|
||||||
#: models.py:292
|
#: models.py:292
|
||||||
msgid "start"
|
msgid "start"
|
||||||
msgstr ""
|
msgstr "iniciar"
|
||||||
|
|
||||||
#: models.py:293
|
#: models.py:293
|
||||||
msgid "end"
|
msgid "end"
|
||||||
msgstr ""
|
msgstr "finalitzar"
|
||||||
|
|
||||||
#: models.py:295
|
#: models.py:295
|
||||||
msgid "Informative link back to the order"
|
msgid "Informative link back to the order"
|
||||||
msgstr ""
|
msgstr "Enllaç informatiu de l'ordre"
|
||||||
|
|
||||||
#: models.py:296
|
#: models.py:296
|
||||||
msgid "order billed"
|
msgid "order billed"
|
||||||
msgstr ""
|
msgstr "ordre facturada"
|
||||||
|
|
||||||
#: models.py:297
|
#: models.py:297
|
||||||
msgid "order billed until"
|
msgid "order billed until"
|
||||||
msgstr ""
|
msgstr "ordre facturada fins a"
|
||||||
|
|
||||||
#: models.py:298
|
#: models.py:298
|
||||||
msgid "created"
|
msgid "created"
|
||||||
msgstr ""
|
msgstr "creada"
|
||||||
|
|
||||||
#: models.py:300
|
#: models.py:300
|
||||||
msgid "amended line"
|
msgid "amended line"
|
||||||
msgstr ""
|
msgstr "línia rectificada"
|
||||||
|
|
||||||
#: models.py:343
|
#: models.py:343
|
||||||
msgid "Volume"
|
msgid "Volume"
|
||||||
msgstr ""
|
msgstr "Volum"
|
||||||
|
|
||||||
#: models.py:344
|
#: models.py:344
|
||||||
msgid "Compensation"
|
msgid "Compensation"
|
||||||
msgstr ""
|
msgstr "Compensació"
|
||||||
|
|
||||||
#: models.py:345
|
#: models.py:345
|
||||||
msgid "Other"
|
msgid "Other"
|
||||||
msgstr ""
|
msgstr "Altre"
|
||||||
|
|
||||||
#: models.py:349
|
#: models.py:349
|
||||||
msgid "bill line"
|
msgid "bill line"
|
||||||
msgstr ""
|
msgstr "línia de factura"
|
||||||
|
|
||||||
#: templates/bills/microspective-fee.html:107
|
#: templates/bills/microspective-fee.html:107
|
||||||
msgid "Due date"
|
msgid "Due date"
|
||||||
msgstr ""
|
msgstr "Data de pagament"
|
||||||
|
|
||||||
#: templates/bills/microspective-fee.html:108
|
#: templates/bills/microspective-fee.html:108
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "On %(bank_account)s"
|
msgid "On %(bank_account)s"
|
||||||
msgstr ""
|
msgstr "Al %(bank_account)s"
|
||||||
|
|
||||||
#: templates/bills/microspective-fee.html:114
|
#: templates/bills/microspective-fee.html:114
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "From %(ini)s to %(end)s"
|
msgid "From %(ini)s to %(end)s"
|
||||||
msgstr ""
|
msgstr "De %(ini)s a %(end)s"
|
||||||
|
|
||||||
#: templates/bills/microspective-fee.html:121
|
#: templates/bills/microspective-fee.html:121
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
"<strong>With your membership</strong> you are supporting ...\n"
|
"<strong>With your membership</strong> you are supporting ...\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
"<strong>Amb la teva quota de soci</strong> estàs donant suport ...\n"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:49
|
#: templates/bills/microspective.html:49
|
||||||
msgid "DUE DATE"
|
msgid "DUE DATE"
|
||||||
|
@ -411,18 +417,17 @@ msgid "TOTAL"
|
||||||
msgstr "TOTAL"
|
msgstr "TOTAL"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:57
|
#: templates/bills/microspective.html:57
|
||||||
#, fuzzy, python-format
|
#, python-format
|
||||||
#| msgid "%(bill_type|upper)s DATE "
|
|
||||||
msgid "%(bill_type)s DATE"
|
msgid "%(bill_type)s DATE"
|
||||||
msgstr "DATA %(bill_type|upper)s"
|
msgstr "DATA %(bill_type)s"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:74
|
#: templates/bills/microspective.html:74
|
||||||
msgid "period"
|
msgid "period"
|
||||||
msgstr ""
|
msgstr "període"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:75
|
#: templates/bills/microspective.html:75
|
||||||
msgid "hrs/qty"
|
msgid "hrs/qty"
|
||||||
msgstr "hrs/quant"
|
msgstr "hrs/qnt"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:76
|
#: templates/bills/microspective.html:76
|
||||||
msgid "rate/price"
|
msgid "rate/price"
|
||||||
|
@ -446,15 +451,6 @@ msgid "PAYMENT"
|
||||||
msgstr "PAGAMENT"
|
msgstr "PAGAMENT"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:140
|
#: templates/bills/microspective.html:140
|
||||||
#, fuzzy, python-format
|
|
||||||
#| msgid ""
|
|
||||||
#| "\n"
|
|
||||||
#| " You can pay our <i>%(type)s</i> by bank transfer. "
|
|
||||||
#| "<br>\n"
|
|
||||||
#| " Please make sure to state your name and the <i>"
|
|
||||||
#| "%(type)s</i> number.\n"
|
|
||||||
#| " Our bank account number is <br>\n"
|
|
||||||
#| " "
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
" You can pay our <i>%(type)s</i> by bank transfer.<br>\n"
|
" You can pay our <i>%(type)s</i> by bank transfer.<br>\n"
|
||||||
|
@ -464,8 +460,8 @@ msgid ""
|
||||||
" "
|
" "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"Pots pagar aquesta <i>%(type)s</i> per transferencia banacaria.<br>Inclou el "
|
"Pots pagar aquesta <i>%(type)s</i> per transferència bancaria.<br>Inclou el "
|
||||||
"teu nom i el numero de <i>%(type)s</i>. El nostre compte bancari és"
|
"teu nom i el número de <i>%(type)s</i>. El nostre compte bancari és"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:149
|
#: templates/bills/microspective.html:149
|
||||||
msgid "QUESTIONS"
|
msgid "QUESTIONS"
|
||||||
|
@ -481,3 +477,9 @@ msgid ""
|
||||||
" your message.\n"
|
" your message.\n"
|
||||||
" "
|
" "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" Si tens algun dubte o pregunta sobre la teva <i>%(type)s</i>, si "
|
||||||
|
"us plau\n"
|
||||||
|
" contacta amb nosaltres a %(email)s. Et respondrem el més "
|
||||||
|
"ràpidament possible.\n"
|
||||||
|
" "
|
||||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2015-05-28 09:23+0000\n"
|
"POT-Creation-Date: 2015-05-28 12:31+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -20,47 +20,49 @@ msgstr ""
|
||||||
|
|
||||||
#: actions.py:37
|
#: actions.py:37
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr ""
|
msgstr "Descarga"
|
||||||
|
|
||||||
#: actions.py:47
|
#: actions.py:47
|
||||||
msgid "View"
|
msgid "View"
|
||||||
msgstr ""
|
msgstr "Vista"
|
||||||
|
|
||||||
#: actions.py:55
|
#: actions.py:55
|
||||||
msgid "Selected bills should be in open state"
|
msgid "Selected bills should be in open state"
|
||||||
msgstr ""
|
msgstr "Las facturas seleccionadas están en estado abierto"
|
||||||
|
|
||||||
#: actions.py:73
|
#: actions.py:73
|
||||||
msgid "Selected bills have been closed"
|
msgid "Selected bills have been closed"
|
||||||
msgstr ""
|
msgstr "Las facturas seleccionadas han sido cerradas"
|
||||||
|
|
||||||
#: actions.py:86
|
#: actions.py:86
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "<a href=\"%(url)s\">One related transaction</a> has been created"
|
msgid "<a href=\"%(url)s\">One related transaction</a> has been created"
|
||||||
msgstr ""
|
msgstr "Se ha creado una <a href=\"%(url)s\">transacción</a>"
|
||||||
|
|
||||||
#: actions.py:87
|
#: actions.py:87
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "<a href=\"%(url)s\">%(num)i related transactions</a> have been created"
|
msgid "<a href=\"%(url)s\">%(num)i related transactions</a> have been created"
|
||||||
msgstr ""
|
msgstr "Se han creado <a href=\"%(url)s\">%(num)i transacciones</a>"
|
||||||
|
|
||||||
#: actions.py:93
|
#: actions.py:93
|
||||||
msgid "Are you sure about closing the following bills?"
|
msgid "Are you sure about closing the following bills?"
|
||||||
msgstr ""
|
msgstr "Estás a punto de cerrar las sigüientes facturas. ¿Estás seguro?"
|
||||||
|
|
||||||
#: actions.py:94
|
#: actions.py:94
|
||||||
msgid ""
|
msgid ""
|
||||||
"Once a bill is closed it can not be further modified.</p><p>Please select a "
|
"Once a bill is closed it can not be further modified.</p><p>Please select a "
|
||||||
"payment source for the selected bills"
|
"payment source for the selected bills"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Una vez cerrada la factura ya no se podrá modificar.</p><p>Por favor "
|
||||||
|
"seleciona un metodo de pago para las facturas seleccionadas"
|
||||||
|
|
||||||
#: actions.py:107
|
#: actions.py:107
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr ""
|
msgstr "Cerrar"
|
||||||
|
|
||||||
#: actions.py:125
|
#: actions.py:125
|
||||||
msgid "One bill has been sent."
|
msgid "One bill has been sent."
|
||||||
msgstr ""
|
msgstr "Se ha enviado una factura"
|
||||||
|
|
||||||
#: actions.py:126
|
#: actions.py:126
|
||||||
#, python-format
|
#, python-format
|
||||||
|
@ -143,7 +145,7 @@ msgstr ""
|
||||||
|
|
||||||
#: admin.py:243
|
#: admin.py:243
|
||||||
msgid "Payment"
|
msgid "Payment"
|
||||||
msgstr ""
|
msgstr "Pago"
|
||||||
|
|
||||||
#: filters.py:17
|
#: filters.py:17
|
||||||
msgid "All"
|
msgid "All"
|
||||||
|
@ -151,19 +153,19 @@ msgstr ""
|
||||||
|
|
||||||
#: filters.py:18 models.py:78
|
#: filters.py:18 models.py:78
|
||||||
msgid "Invoice"
|
msgid "Invoice"
|
||||||
msgstr ""
|
msgstr "Factura"
|
||||||
|
|
||||||
#: filters.py:19 models.py:79
|
#: filters.py:19 models.py:79
|
||||||
msgid "Amendment invoice"
|
msgid "Amendment invoice"
|
||||||
msgstr ""
|
msgstr "Factura rectificative"
|
||||||
|
|
||||||
#: filters.py:20 models.py:80
|
#: filters.py:20 models.py:80
|
||||||
msgid "Fee"
|
msgid "Fee"
|
||||||
msgstr ""
|
msgstr "Quota de socio"
|
||||||
|
|
||||||
#: filters.py:21
|
#: filters.py:21
|
||||||
msgid "Amendment fee"
|
msgid "Amendment fee"
|
||||||
msgstr ""
|
msgstr "Quota rectificativa"
|
||||||
|
|
||||||
#: filters.py:22
|
#: filters.py:22
|
||||||
msgid "Pro-forma"
|
msgid "Pro-forma"
|
||||||
|
@ -382,17 +384,17 @@ msgstr ""
|
||||||
|
|
||||||
#: templates/bills/microspective-fee.html:107
|
#: templates/bills/microspective-fee.html:107
|
||||||
msgid "Due date"
|
msgid "Due date"
|
||||||
msgstr ""
|
msgstr "Fecha de pago"
|
||||||
|
|
||||||
#: templates/bills/microspective-fee.html:108
|
#: templates/bills/microspective-fee.html:108
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "On %(bank_account)s"
|
msgid "On %(bank_account)s"
|
||||||
msgstr ""
|
msgstr "En %(bank_account)s"
|
||||||
|
|
||||||
#: templates/bills/microspective-fee.html:114
|
#: templates/bills/microspective-fee.html:114
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "From %(ini)s to %(end)s"
|
msgid "From %(ini)s to %(end)s"
|
||||||
msgstr ""
|
msgstr "Desde %(ini)s hasta %(end)s"
|
||||||
|
|
||||||
#: templates/bills/microspective-fee.html:121
|
#: templates/bills/microspective-fee.html:121
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -402,45 +404,45 @@ msgstr ""
|
||||||
|
|
||||||
#: templates/bills/microspective.html:49
|
#: templates/bills/microspective.html:49
|
||||||
msgid "DUE DATE"
|
msgid "DUE DATE"
|
||||||
msgstr ""
|
msgstr "VENCIMIENTO"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:53
|
#: templates/bills/microspective.html:53
|
||||||
msgid "TOTAL"
|
msgid "TOTAL"
|
||||||
msgstr ""
|
msgstr "TOTAL"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:57
|
#: templates/bills/microspective.html:57
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(bill_type)s DATE"
|
msgid "%(bill_type)s DATE"
|
||||||
msgstr ""
|
msgstr "FECHA %(bill_type)s"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:74
|
#: templates/bills/microspective.html:74
|
||||||
msgid "period"
|
msgid "period"
|
||||||
msgstr ""
|
msgstr "periodo"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:75
|
#: templates/bills/microspective.html:75
|
||||||
msgid "hrs/qty"
|
msgid "hrs/qty"
|
||||||
msgstr ""
|
msgstr "hrs/cant"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:76
|
#: templates/bills/microspective.html:76
|
||||||
msgid "rate/price"
|
msgid "rate/price"
|
||||||
msgstr ""
|
msgstr "tarifa/precio"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:111
|
#: templates/bills/microspective.html:111
|
||||||
#: templates/bills/microspective.html:114
|
#: templates/bills/microspective.html:114
|
||||||
msgid "VAT"
|
msgid "VAT"
|
||||||
msgstr ""
|
msgstr "IVA"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:114
|
#: templates/bills/microspective.html:114
|
||||||
msgid "taxes"
|
msgid "taxes"
|
||||||
msgstr ""
|
msgstr "impuestos"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:130
|
#: templates/bills/microspective.html:130
|
||||||
msgid "COMMENTS"
|
msgid "COMMENTS"
|
||||||
msgstr ""
|
msgstr "COMENTARIOS"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:136
|
#: templates/bills/microspective.html:136
|
||||||
msgid "PAYMENT"
|
msgid "PAYMENT"
|
||||||
msgstr ""
|
msgstr "PAGO"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:140
|
#: templates/bills/microspective.html:140
|
||||||
#, python-format
|
#, python-format
|
||||||
|
@ -452,6 +454,9 @@ msgid ""
|
||||||
" Our bank account number is <br>\n"
|
" Our bank account number is <br>\n"
|
||||||
" "
|
" "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
"Puedes pagar esta <i>%(type)s</i> por transferencia bancaria.<br>Incloye tu "
|
||||||
|
"nombre y el número de <i>%(type)s</i>. Nuestra cuenta bancaria es"
|
||||||
|
|
||||||
#: templates/bills/microspective.html:149
|
#: templates/bills/microspective.html:149
|
||||||
msgid "QUESTIONS"
|
msgid "QUESTIONS"
|
||||||
|
@ -467,3 +472,9 @@ msgid ""
|
||||||
" your message.\n"
|
" your message.\n"
|
||||||
" "
|
" "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" Si tienes alguna duda o pregunta sobre tu <i>%(type)s</i>, por "
|
||||||
|
"favor\n"
|
||||||
|
" contacta con nosotros en %(email)s. Te responderemos lo más "
|
||||||
|
"rapidamente posible.\n"
|
||||||
|
" "
|
||||||
|
|
|
@ -142,7 +142,7 @@ class Bill(models.Model):
|
||||||
def get_type(self):
|
def get_type(self):
|
||||||
return self.type or self.get_class_type()
|
return self.type or self.get_class_type()
|
||||||
|
|
||||||
def set_number(self):
|
def get_number(self):
|
||||||
cls = type(self)
|
cls = type(self)
|
||||||
bill_type = self.get_type()
|
bill_type = self.get_type()
|
||||||
if bill_type == self.BILL:
|
if bill_type == self.BILL:
|
||||||
|
@ -162,7 +162,7 @@ class Bill(models.Model):
|
||||||
number_length = settings.BILLS_NUMBER_LENGTH
|
number_length = settings.BILLS_NUMBER_LENGTH
|
||||||
zeros = (number_length - len(str(number))) * '0'
|
zeros = (number_length - len(str(number))) * '0'
|
||||||
number = zeros + str(number)
|
number = zeros + str(number)
|
||||||
self.number = '{prefix}{year}{number}'.format(prefix=prefix, year=year, number=number)
|
return '{prefix}{year}{number}'.format(prefix=prefix, year=year, number=number)
|
||||||
|
|
||||||
def get_due_date(self, payment=None):
|
def get_due_date(self, payment=None):
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
|
@ -178,13 +178,14 @@ class Bill(models.Model):
|
||||||
if not self.due_on:
|
if not self.due_on:
|
||||||
self.due_on = self.get_due_date(payment=payment)
|
self.due_on = self.get_due_date(payment=payment)
|
||||||
self.total = self.get_total()
|
self.total = self.get_total()
|
||||||
self.html = self.render(payment=payment)
|
|
||||||
transaction = None
|
transaction = None
|
||||||
if self.get_type() != self.PROFORMA:
|
if self.get_type() != self.PROFORMA:
|
||||||
transaction = self.transactions.create(bill=self, source=payment, amount=self.total)
|
transaction = self.transactions.create(bill=self, source=payment, amount=self.total)
|
||||||
self.closed_on = timezone.now()
|
self.closed_on = timezone.now()
|
||||||
self.is_open = False
|
self.is_open = False
|
||||||
self.is_sent = False
|
self.is_sent = False
|
||||||
|
self.number = self.get_number()
|
||||||
|
self.html = self.render(payment=payment)
|
||||||
self.save()
|
self.save()
|
||||||
return transaction
|
return transaction
|
||||||
|
|
||||||
|
@ -207,37 +208,37 @@ class Bill(models.Model):
|
||||||
self.save(update_fields=['is_sent'])
|
self.save(update_fields=['is_sent'])
|
||||||
|
|
||||||
def render(self, payment=False, language=None):
|
def render(self, payment=False, language=None):
|
||||||
if payment is False:
|
|
||||||
payment = self.account.paymentsources.get_default()
|
|
||||||
context = Context({
|
|
||||||
'bill': self,
|
|
||||||
'lines': self.lines.all().prefetch_related('sublines'),
|
|
||||||
'seller': self.seller,
|
|
||||||
'buyer': self.buyer,
|
|
||||||
'seller_info': {
|
|
||||||
'phone': settings.BILLS_SELLER_PHONE,
|
|
||||||
'website': settings.BILLS_SELLER_WEBSITE,
|
|
||||||
'email': settings.BILLS_SELLER_EMAIL,
|
|
||||||
'bank_account': settings.BILLS_SELLER_BANK_ACCOUNT,
|
|
||||||
},
|
|
||||||
'currency': settings.BILLS_CURRENCY,
|
|
||||||
'payment': payment and payment.get_bill_context(),
|
|
||||||
'default_due_date': self.get_due_date(payment=payment),
|
|
||||||
'now': timezone.now(),
|
|
||||||
})
|
|
||||||
template_name = 'BILLS_%s_TEMPLATE' % self.get_type()
|
|
||||||
template = getattr(settings, template_name, settings.BILLS_DEFAULT_TEMPLATE)
|
|
||||||
bill_template = loader.get_template(template)
|
|
||||||
with translation.override(language or self.account.language):
|
with translation.override(language or self.account.language):
|
||||||
|
if payment is False:
|
||||||
|
payment = self.account.paymentsources.get_default()
|
||||||
|
context = Context({
|
||||||
|
'bill': self,
|
||||||
|
'lines': self.lines.all().prefetch_related('sublines'),
|
||||||
|
'seller': self.seller,
|
||||||
|
'buyer': self.buyer,
|
||||||
|
'seller_info': {
|
||||||
|
'phone': settings.BILLS_SELLER_PHONE,
|
||||||
|
'website': settings.BILLS_SELLER_WEBSITE,
|
||||||
|
'email': settings.BILLS_SELLER_EMAIL,
|
||||||
|
'bank_account': settings.BILLS_SELLER_BANK_ACCOUNT,
|
||||||
|
},
|
||||||
|
'currency': settings.BILLS_CURRENCY,
|
||||||
|
'payment': payment and payment.get_bill_context(),
|
||||||
|
'default_due_date': self.get_due_date(payment=payment),
|
||||||
|
'now': timezone.now(),
|
||||||
|
})
|
||||||
|
template_name = 'BILLS_%s_TEMPLATE' % self.get_type()
|
||||||
|
template = getattr(settings, template_name, settings.BILLS_DEFAULT_TEMPLATE)
|
||||||
|
bill_template = loader.get_template(template)
|
||||||
html = bill_template.render(context)
|
html = bill_template.render(context)
|
||||||
html = html.replace('-pageskip-', '<pdf:nextpage />')
|
html = html.replace('-pageskip-', '<pdf:nextpage />')
|
||||||
return html
|
return html
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.type:
|
if not self.type:
|
||||||
self.type = self.get_type()
|
self.type = self.get_type()
|
||||||
if not self.number or (self.number.startswith('O') and not self.is_open):
|
if not self.number:
|
||||||
self.set_number()
|
self.number = self.get_number()
|
||||||
super(Bill, self).save(*args, **kwargs)
|
super(Bill, self).save(*args, **kwargs)
|
||||||
|
|
||||||
def get_subtotals(self):
|
def get_subtotals(self):
|
||||||
|
|
|
@ -175,12 +175,12 @@ a:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
#lines .column-description {
|
#lines .column-description {
|
||||||
width: 40%;
|
width: 39%;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
#lines .column-period {
|
#lines .column-period {
|
||||||
width: 22%;
|
width: 23%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#lines .column-quantity {
|
#lines .column-quantity {
|
||||||
|
|
|
@ -135,7 +135,7 @@
|
||||||
<div id="payment">
|
<div id="payment">
|
||||||
<span class="title">{% trans "PAYMENT" %}</span>
|
<span class="title">{% trans "PAYMENT" %}</span>
|
||||||
{% if payment.message %}
|
{% if payment.message %}
|
||||||
{{ payment.message | safe }}
|
{{ payment.message|safe }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% blocktrans with type=bill.get_type_display.lower %}
|
{% blocktrans with type=bill.get_type_display.lower %}
|
||||||
You can pay our <i>{{ type }}</i> by bank transfer.<br>
|
You can pay our <i>{{ type }}</i> by bank transfer.<br>
|
||||||
|
|
|
@ -12,11 +12,10 @@ class EmailBackend(BaseEmailBackend):
|
||||||
"""
|
"""
|
||||||
A wrapper that manages a queued SMTP system.
|
A wrapper that manages a queued SMTP system.
|
||||||
"""
|
"""
|
||||||
messages = 0
|
|
||||||
|
|
||||||
def send_messages(self, email_messages):
|
def send_messages(self, email_messages):
|
||||||
if not email_messages:
|
if not email_messages:
|
||||||
return
|
return
|
||||||
|
# Count messages per request
|
||||||
cache = get_request_cache()
|
cache = get_request_cache()
|
||||||
key = 'mailer.sent_messages'
|
key = 'mailer.sent_messages'
|
||||||
sent_messages = cache.get(key) or 0
|
sent_messages = cache.get(key) or 0
|
||||||
|
@ -24,7 +23,7 @@ class EmailBackend(BaseEmailBackend):
|
||||||
cache.set(key, sent_messages)
|
cache.set(key, sent_messages)
|
||||||
|
|
||||||
is_bulk = len(email_messages) > 1
|
is_bulk = len(email_messages) > 1
|
||||||
if sent_messages > settings.MAILER_NON_QUEUED_MAILS_PER_REQUEST_THRESHOLD:
|
if sent_messages > settings.MAILER_NON_QUEUED_PER_REQUEST_THRESHOLD:
|
||||||
is_bulk = True
|
is_bulk = True
|
||||||
default_priority = Message.NORMAL if is_bulk else Message.CRITICAL
|
default_priority = Message.NORMAL if is_bulk else Message.CRITICAL
|
||||||
num_sent = 0
|
num_sent = 0
|
||||||
|
|
|
@ -14,6 +14,8 @@ from .models import Message
|
||||||
|
|
||||||
|
|
||||||
def send_message(message, num=0, connection=None, bulk=100):
|
def send_message(message, num=0, connection=None, bulk=100):
|
||||||
|
if not message.pk:
|
||||||
|
message.save()
|
||||||
if num >= bulk:
|
if num >= bulk:
|
||||||
connection.close()
|
connection.close()
|
||||||
connection = None
|
connection = None
|
||||||
|
|
|
@ -50,7 +50,7 @@ class Message(models.Model):
|
||||||
|
|
||||||
def sent(self):
|
def sent(self):
|
||||||
self.state = self.SENT
|
self.state = self.SENT
|
||||||
self.save()
|
self.save(update_fiields=('state',))
|
||||||
|
|
||||||
def log(self, error):
|
def log(self, error):
|
||||||
result = SMTPLog.SUCCESS
|
result = SMTPLog.SUCCESS
|
||||||
|
|
|
@ -13,7 +13,7 @@ MAILER_MESSAGES_CLEANUP_DAYS = Setting('MAILER_MESSAGES_CLEANUP_DAYS',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
MAILER_NON_QUEUED_MAILS_PER_REQUEST_THRESHOLD = Setting('MAILER_NON_QUEUED_MAILS_PER_REQUEST_THRESHOLD',
|
MAILER_NON_QUEUED_PER_REQUEST_THRESHOLD = Setting('MAILER_NON_QUEUED_PER_REQUEST_THRESHOLD',
|
||||||
2,
|
2,
|
||||||
help_text=_("Number of emails that will be sent directly before starting to queue them."),
|
help_text=_("Number of emails that will be sent immediately before starting to queue them."),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.contrib.admin import actions
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
@ -18,23 +19,25 @@ from .models import Transaction
|
||||||
def process_transactions(modeladmin, request, queryset):
|
def process_transactions(modeladmin, request, queryset):
|
||||||
processes = []
|
processes = []
|
||||||
if queryset.exclude(state=Transaction.WAITTING_PROCESSING).exists():
|
if queryset.exclude(state=Transaction.WAITTING_PROCESSING).exists():
|
||||||
msg = _("Selected transactions must be on '{state}' state")
|
messages.error(request,
|
||||||
messages.error(request, msg.format(state=Transaction.WAITTING_PROCESSING))
|
_("Selected transactions must be on '{state}' state").format(
|
||||||
|
state=Transaction.WAITTING_PROCESSING)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
for method, transactions in queryset.group_by('source__method').items():
|
for method, transactions in queryset.group_by('source__method').items():
|
||||||
if method is not None:
|
if method is not None:
|
||||||
method = PaymentMethod.get(method)
|
method = PaymentMethod.get(method)
|
||||||
procs = method.process(transactions)
|
procs = method.process(transactions)
|
||||||
processes += procs
|
processes += procs
|
||||||
for trans in transactions:
|
for transaction in transactions:
|
||||||
modeladmin.log_change(request, trans, _("Processed"))
|
modeladmin.log_change(request, transaction, _("Processed"))
|
||||||
if not processes:
|
if not processes:
|
||||||
return
|
return
|
||||||
opts = modeladmin.model._meta
|
opts = modeladmin.model._meta
|
||||||
num = len(queryset)
|
num = len(queryset)
|
||||||
context = {
|
context = {
|
||||||
'title': ungettext(
|
'title': ungettext(
|
||||||
_("Selected transaction has been processed."),
|
_("One selected transaction has been processed."),
|
||||||
_("%s Selected transactions have been processed.") % num,
|
_("%s Selected transactions have been processed.") % num,
|
||||||
num),
|
num),
|
||||||
'content_message': ungettext(
|
'content_message': ungettext(
|
||||||
|
@ -54,9 +57,9 @@ def process_transactions(modeladmin, request, queryset):
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
@action_with_confirmation()
|
@action_with_confirmation()
|
||||||
def mark_as_executed(modeladmin, request, queryset):
|
def mark_as_executed(modeladmin, request, queryset):
|
||||||
for trans in queryset:
|
for transaction in queryset:
|
||||||
trans.mark_as_executed()
|
transaction.mark_as_executed()
|
||||||
modeladmin.log_change(request, trans, _("Executed"))
|
modeladmin.log_change(request, transaction, _("Executed"))
|
||||||
num = len(queryset)
|
num = len(queryset)
|
||||||
msg = ungettext(
|
msg = ungettext(
|
||||||
_("One selected transaction has been marked as executed."),
|
_("One selected transaction has been marked as executed."),
|
||||||
|
@ -70,9 +73,9 @@ mark_as_executed.verbose_name = _("Mark as executed")
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
@action_with_confirmation()
|
@action_with_confirmation()
|
||||||
def mark_as_secured(modeladmin, request, queryset):
|
def mark_as_secured(modeladmin, request, queryset):
|
||||||
for trans in queryset:
|
for transaction in queryset:
|
||||||
trans.mark_as_secured()
|
transaction.mark_as_secured()
|
||||||
modeladmin.log_change(request, trans, _("Secured"))
|
modeladmin.log_change(request, transaction, _("Secured"))
|
||||||
num = len(queryset)
|
num = len(queryset)
|
||||||
msg = ungettext(
|
msg = ungettext(
|
||||||
_("One selected transaction has been marked as secured."),
|
_("One selected transaction has been marked as secured."),
|
||||||
|
@ -86,9 +89,9 @@ mark_as_secured.verbose_name = _("Mark as secured")
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
@action_with_confirmation()
|
@action_with_confirmation()
|
||||||
def mark_as_rejected(modeladmin, request, queryset):
|
def mark_as_rejected(modeladmin, request, queryset):
|
||||||
for trans in queryset:
|
for transaction in queryset:
|
||||||
trans.mark_as_rejected()
|
transaction.mark_as_rejected()
|
||||||
modeladmin.log_change(request, trans, _("Rejected"))
|
modeladmin.log_change(request, transaction, _("Rejected"))
|
||||||
num = len(queryset)
|
num = len(queryset)
|
||||||
msg = ungettext(
|
msg = ungettext(
|
||||||
_("One selected transaction has been marked as rejected."),
|
_("One selected transaction has been marked as rejected."),
|
||||||
|
@ -157,9 +160,9 @@ abort.verbose_name = _("Abort")
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
@action_with_confirmation(extra_context=_format_commit)
|
@action_with_confirmation(extra_context=_format_commit)
|
||||||
def commit(modeladmin, request, queryset):
|
def commit(modeladmin, request, queryset):
|
||||||
for trans in queryset:
|
for transaction in queryset:
|
||||||
trans.mark_as_rejected()
|
transaction.mark_as_rejected()
|
||||||
modeladmin.log_change(request, trans, _("Rejected"))
|
modeladmin.log_change(request, transaction, _("Rejected"))
|
||||||
num = len(queryset)
|
num = len(queryset)
|
||||||
msg = ungettext(
|
msg = ungettext(
|
||||||
_("One selected transaction has been marked as rejected."),
|
_("One selected transaction has been marked as rejected."),
|
||||||
|
@ -168,3 +171,29 @@ def commit(modeladmin, request, queryset):
|
||||||
modeladmin.message_user(request, msg)
|
modeladmin.message_user(request, msg)
|
||||||
commit.url_name = 'commit'
|
commit.url_name = 'commit'
|
||||||
commit.verbose_name = _("Commit")
|
commit.verbose_name = _("Commit")
|
||||||
|
|
||||||
|
|
||||||
|
def delete_selected(modeladmin, request, queryset):
|
||||||
|
""" Has to have same name as admin.actions.delete_selected """
|
||||||
|
if not queryset:
|
||||||
|
messages.warning(request, "No transaction process selected.")
|
||||||
|
return
|
||||||
|
if queryset.exclude(transactions__state=Transaction.WAITTING_EXECUTION).exists():
|
||||||
|
messages.error(request, "Done nothing. Not all related transactions in waitting execution.")
|
||||||
|
return
|
||||||
|
# Store before deleting
|
||||||
|
related_transactions = []
|
||||||
|
for process in queryset:
|
||||||
|
related_transactions.extend(process.transactions.filter(state=Transaction.WAITTING_EXECUTION))
|
||||||
|
response = actions.delete_selected(modeladmin, request, queryset)
|
||||||
|
if response is None:
|
||||||
|
# Confirmation
|
||||||
|
num = 0
|
||||||
|
for transaction in related_transactions:
|
||||||
|
transaction.state = Transaction.WAITTING_PROCESSING
|
||||||
|
transaction.save(update_fields=('state',))
|
||||||
|
num += 1
|
||||||
|
modeladmin.log_change(request, transaction, _("Unprocessed"))
|
||||||
|
messages.success(request, "%i related transactions marked as waitting for processing." % num)
|
||||||
|
return response
|
||||||
|
delete_selected.short_description = actions.delete_selected.short_description
|
||||||
|
|
|
@ -122,8 +122,8 @@ class TransactionProcessAdmin(ChangeViewActionsMixin, admin.ModelAdmin):
|
||||||
fields = ('data', 'file_url', 'created_at')
|
fields = ('data', 'file_url', 'created_at')
|
||||||
readonly_fields = ('data', 'file_url', 'display_transactions', 'created_at')
|
readonly_fields = ('data', 'file_url', 'display_transactions', 'created_at')
|
||||||
inlines = [TransactionInline]
|
inlines = [TransactionInline]
|
||||||
actions = (actions.mark_process_as_executed, actions.abort, actions.commit)
|
change_view_actions = (actions.mark_process_as_executed, actions.abort, actions.commit)
|
||||||
change_view_actions = actions
|
actions = change_view_actions + (actions.delete_selected,)
|
||||||
|
|
||||||
def file_url(self, process):
|
def file_url(self, process):
|
||||||
if process.file:
|
if process.file:
|
||||||
|
@ -138,7 +138,7 @@ class TransactionProcessAdmin(ChangeViewActionsMixin, admin.ModelAdmin):
|
||||||
# Because of values_list this query doesn't benefit from prefetch_related
|
# Because of values_list this query doesn't benefit from prefetch_related
|
||||||
tx_ids = process.transactions.values_list('id', flat=True)
|
tx_ids = process.transactions.values_list('id', flat=True)
|
||||||
for tx_id in tx_ids:
|
for tx_id in tx_ids:
|
||||||
ids.append('#%i' % tx_id)
|
ids.append(str(tx_id))
|
||||||
counter += 1
|
counter += 1
|
||||||
if counter > 10:
|
if counter > 10:
|
||||||
counter = 0
|
counter = 0
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,250 @@
|
||||||
|
# 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: 2015-05-28 16:40+0000\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"
|
||||||
|
|
||||||
|
#: actions.py:21
|
||||||
|
msgid "Selected transactions must be on '{state}' state"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:30
|
||||||
|
msgid "Processed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:37
|
||||||
|
msgid "Selected transaction has been processed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:38
|
||||||
|
#, python-format
|
||||||
|
msgid "%s Selected transactions have been processed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:41
|
||||||
|
msgid ""
|
||||||
|
"The following transaction process has been generated, you may want to save "
|
||||||
|
"it on your computer now."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:43
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"The following %s transaction processes have been generated, you may want to "
|
||||||
|
"save it on your computer now."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:46
|
||||||
|
msgid "Process"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:59 actions.py:130 models.py:93 models.py:161
|
||||||
|
msgid "Executed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:62
|
||||||
|
msgid "One selected transaction has been marked as executed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:63
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected transactions have been marked as executed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:67 actions.py:138
|
||||||
|
msgid "Mark as executed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:75 models.py:94
|
||||||
|
msgid "Secured"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:78
|
||||||
|
msgid "One selected transaction has been marked as secured."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:79
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected transactions have been marked as secured."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:83
|
||||||
|
msgid "Mark as secured"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:91 actions.py:162 models.py:95
|
||||||
|
msgid "Rejected"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:94 actions.py:165
|
||||||
|
msgid "One selected transaction has been marked as rejected."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:95 actions.py:166
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected transactions have been marked as rejected."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:99
|
||||||
|
msgid "Mark as rejected"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:133
|
||||||
|
msgid "One selected process has been marked as executed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:134
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected processes have been marked as executed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:146 models.py:162
|
||||||
|
msgid "Aborted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:149
|
||||||
|
msgid "One selected process has been aborted."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:150
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected processes have been aborted."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:154
|
||||||
|
msgid "Abort"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:170
|
||||||
|
msgid "Commit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:42
|
||||||
|
msgid "ID"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:101
|
||||||
|
msgid "proc"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:152
|
||||||
|
msgid "Transactions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/creditcard.py:11
|
||||||
|
msgid "Label"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/creditcard.py:12
|
||||||
|
msgid "Use a name such as \"Jo's Visa\" to remember which card it is."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/creditcard.py:30
|
||||||
|
msgid "Credit card"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/sepadirectdebit.py:23 methods/sepadirectdebit.py:30
|
||||||
|
msgid "Name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/sepadirectdebit.py:39
|
||||||
|
msgid "SEPA Direct Debit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/sepadirectdebit.py:48
|
||||||
|
msgid ""
|
||||||
|
"This bill will be automatically charged to your bank account with IBAN "
|
||||||
|
"number<br><strong>%s</strong>."
|
||||||
|
msgstr ""
|
||||||
|
"Aquesta factura es cobrarà automaticament en el teu compte bancari amb IBAN "
|
||||||
|
"<br><strong>%s</strong>."
|
||||||
|
|
||||||
|
#: models.py:19
|
||||||
|
msgid "account"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:21
|
||||||
|
msgid "method"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:23 models.py:166
|
||||||
|
msgid "data"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:24
|
||||||
|
msgid "active"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:91
|
||||||
|
msgid "Waitting processing"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:92
|
||||||
|
msgid "Waitting execution"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:98
|
||||||
|
msgid "bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:101
|
||||||
|
msgid "source"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:103
|
||||||
|
msgid "process"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:104 models.py:168
|
||||||
|
msgid "state"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:106
|
||||||
|
msgid "amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:108 models.py:169
|
||||||
|
msgid "created"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:109
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:124
|
||||||
|
msgid "New transactions can not be allocated for this bill."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:160
|
||||||
|
msgid "Created"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:163
|
||||||
|
msgid "Commited"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:167
|
||||||
|
msgid "file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:170
|
||||||
|
msgid "updated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:173
|
||||||
|
msgid "Transaction processes"
|
||||||
|
msgstr ""
|
Binary file not shown.
|
@ -0,0 +1,250 @@
|
||||||
|
# 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: 2015-05-28 16:40+0000\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"
|
||||||
|
|
||||||
|
#: actions.py:21
|
||||||
|
msgid "Selected transactions must be on '{state}' state"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:30
|
||||||
|
msgid "Processed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:37
|
||||||
|
msgid "Selected transaction has been processed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:38
|
||||||
|
#, python-format
|
||||||
|
msgid "%s Selected transactions have been processed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:41
|
||||||
|
msgid ""
|
||||||
|
"The following transaction process has been generated, you may want to save "
|
||||||
|
"it on your computer now."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:43
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"The following %s transaction processes have been generated, you may want to "
|
||||||
|
"save it on your computer now."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:46
|
||||||
|
msgid "Process"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:59 actions.py:130 models.py:93 models.py:161
|
||||||
|
msgid "Executed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:62
|
||||||
|
msgid "One selected transaction has been marked as executed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:63
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected transactions have been marked as executed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:67 actions.py:138
|
||||||
|
msgid "Mark as executed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:75 models.py:94
|
||||||
|
msgid "Secured"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:78
|
||||||
|
msgid "One selected transaction has been marked as secured."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:79
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected transactions have been marked as secured."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:83
|
||||||
|
msgid "Mark as secured"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:91 actions.py:162 models.py:95
|
||||||
|
msgid "Rejected"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:94 actions.py:165
|
||||||
|
msgid "One selected transaction has been marked as rejected."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:95 actions.py:166
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected transactions have been marked as rejected."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:99
|
||||||
|
msgid "Mark as rejected"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:133
|
||||||
|
msgid "One selected process has been marked as executed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:134
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected processes have been marked as executed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:146 models.py:162
|
||||||
|
msgid "Aborted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:149
|
||||||
|
msgid "One selected process has been aborted."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:150
|
||||||
|
#, python-format
|
||||||
|
msgid "%s selected processes have been aborted."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:154
|
||||||
|
msgid "Abort"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: actions.py:170
|
||||||
|
msgid "Commit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:42
|
||||||
|
msgid "ID"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:101
|
||||||
|
msgid "proc"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: admin.py:152
|
||||||
|
msgid "Transactions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/creditcard.py:11
|
||||||
|
msgid "Label"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/creditcard.py:12
|
||||||
|
msgid "Use a name such as \"Jo's Visa\" to remember which card it is."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/creditcard.py:30
|
||||||
|
msgid "Credit card"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/sepadirectdebit.py:23 methods/sepadirectdebit.py:30
|
||||||
|
msgid "Name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/sepadirectdebit.py:39
|
||||||
|
msgid "SEPA Direct Debit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: methods/sepadirectdebit.py:48
|
||||||
|
msgid ""
|
||||||
|
"This bill will be automatically charged to your bank account with IBAN "
|
||||||
|
"number<br><strong>%s</strong>."
|
||||||
|
msgstr ""
|
||||||
|
"Esta factura se cobrará automaticamente en tu cuenta bancaria con IBAN "
|
||||||
|
"<br><strong>%s</strong>."
|
||||||
|
|
||||||
|
#: models.py:19
|
||||||
|
msgid "account"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:21
|
||||||
|
msgid "method"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:23 models.py:166
|
||||||
|
msgid "data"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:24
|
||||||
|
msgid "active"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:91
|
||||||
|
msgid "Waitting processing"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:92
|
||||||
|
msgid "Waitting execution"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:98
|
||||||
|
msgid "bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:101
|
||||||
|
msgid "source"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:103
|
||||||
|
msgid "process"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:104 models.py:168
|
||||||
|
msgid "state"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:106
|
||||||
|
msgid "amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:108 models.py:169
|
||||||
|
msgid "created"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:109
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:124
|
||||||
|
msgid "New transactions can not be allocated for this bill."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:160
|
||||||
|
msgid "Created"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:163
|
||||||
|
msgid "Commited"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:167
|
||||||
|
msgid "file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:170
|
||||||
|
msgid "updated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:173
|
||||||
|
msgid "Transaction processes"
|
||||||
|
msgstr ""
|
|
@ -45,7 +45,7 @@ class SEPADirectDebit(PaymentMethod):
|
||||||
due_delta = datetime.timedelta(days=5)
|
due_delta = datetime.timedelta(days=5)
|
||||||
|
|
||||||
def get_bill_message(self):
|
def get_bill_message(self):
|
||||||
return _("This bill will been automatically charged to your bank account "
|
return _("This bill will be automatically charged to your bank account "
|
||||||
" with IBAN number<br><strong>%s</strong>.") % self.instance.number
|
" with IBAN number<br><strong>%s</strong>.") % self.instance.number
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -211,7 +211,7 @@ class SEPADirectDebit(PaymentMethod):
|
||||||
),
|
),
|
||||||
E.DbtrAcct( # Debtor Account
|
E.DbtrAcct( # Debtor Account
|
||||||
E.Id(
|
E.Id(
|
||||||
E.IBAN(data['iban'])
|
E.IBAN(data['iban'].replace(' ', ''))
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -246,7 +246,7 @@ class SEPADirectDebit(PaymentMethod):
|
||||||
),
|
),
|
||||||
E.CdtrAcct( # Creditor Account
|
E.CdtrAcct( # Creditor Account
|
||||||
E.Id(
|
E.Id(
|
||||||
E.IBAN(data['iban'])
|
E.IBAN(data['iban'].replace(' ', ''))
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -279,7 +279,8 @@ class SEPADirectDebit(PaymentMethod):
|
||||||
xsd_path = os.path.join(path, xsd)
|
xsd_path = os.path.join(path, xsd)
|
||||||
schema_doc = etree.parse(xsd_path)
|
schema_doc = etree.parse(xsd_path)
|
||||||
schema = etree.XMLSchema(schema_doc)
|
schema = etree.XMLSchema(schema_doc)
|
||||||
sepa = etree.parse(StringIO(etree.tostring(sepa)))
|
sepa = StringIO(etree.tostring(sepa).decode('utf8'))
|
||||||
|
sepa = etree.parse(sepa)
|
||||||
schema.assertValid(sepa)
|
schema.assertValid(sepa)
|
||||||
process.file = file_name
|
process.file = file_name
|
||||||
process.save(update_fields=['file'])
|
process.save(update_fields=['file'])
|
||||||
|
|
|
@ -99,7 +99,7 @@ class Transaction(models.Model):
|
||||||
related_name='transactions')
|
related_name='transactions')
|
||||||
source = models.ForeignKey(PaymentSource, null=True, blank=True,
|
source = models.ForeignKey(PaymentSource, null=True, blank=True,
|
||||||
verbose_name=_("source"), related_name='transactions')
|
verbose_name=_("source"), related_name='transactions')
|
||||||
process = models.ForeignKey('payments.TransactionProcess', null=True,
|
process = models.ForeignKey('payments.TransactionProcess', null=True, on_delete=models.SET_NULL,
|
||||||
blank=True, verbose_name=_("process"), related_name='transactions')
|
blank=True, verbose_name=_("process"), related_name='transactions')
|
||||||
state = models.CharField(_("state"), max_length=32, choices=STATES,
|
state = models.CharField(_("state"), max_length=32, choices=STATES,
|
||||||
default=WAITTING_PROCESSING)
|
default=WAITTING_PROCESSING)
|
||||||
|
@ -111,7 +111,7 @@ class Transaction(models.Model):
|
||||||
objects = TransactionQuerySet.as_manager()
|
objects = TransactionQuerySet.as_manager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Transaction #{}".format(self.id)
|
return "#%i" % self.id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def account(self):
|
def account(self):
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<p>{{ content_message }}</p>
|
<p>{{ content_message }}</p>
|
||||||
<ul>
|
<ul>
|
||||||
{% for proc in processes %}
|
{% for proc in processes %}
|
||||||
<li> <a href="{{ proc.id }}">Process #{{ proc.id }}</a>
|
<li> <a href="{% url admin:payments_transactionprocess_change' proc.pk|admin_urlquote %}">Process #{{ proc.id }}</a>
|
||||||
{% if proc.file %}
|
{% if proc.file %}
|
||||||
<ul><li>File: <a href="{{ proc.file.url }}">{{ proc.file }}</a></li></ul>
|
<ul><li>File: <a href="{{ proc.file.url }}">{{ proc.file }}</a></li></ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -94,4 +94,3 @@ def delete_selected(modeladmin, request, queryset):
|
||||||
return
|
return
|
||||||
return admin.actions.delete_selected(modeladmin, request, queryset)
|
return admin.actions.delete_selected(modeladmin, request, queryset)
|
||||||
delete_selected.short_description = _("Delete selected %(verbose_name_plural)s")
|
delete_selected.short_description = _("Delete selected %(verbose_name_plural)s")
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,8 @@ class SystemUserAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, Extende
|
||||||
add_form = SystemUserCreationForm
|
add_form = SystemUserCreationForm
|
||||||
form = SystemUserChangeForm
|
form = SystemUserChangeForm
|
||||||
ordering = ('-id',)
|
ordering = ('-id',)
|
||||||
actions = (delete_selected, set_permission, disable)
|
change_view_actions = (set_permission, disable)
|
||||||
change_view_actions = actions
|
actions = (delete_selected,) + change_view_actions
|
||||||
|
|
||||||
def display_main(self, user):
|
def display_main(self, user):
|
||||||
return user.is_main
|
return user.is_main
|
||||||
|
|
|
@ -31,10 +31,10 @@ class SystemUser(models.Model):
|
||||||
"""
|
"""
|
||||||
System users
|
System users
|
||||||
|
|
||||||
Username max_length determined by LINUX system user lentgh: 32
|
Username max_length determined by LINUX system user/group lentgh: 32
|
||||||
"""
|
"""
|
||||||
username = models.CharField(_("username"), max_length=32, unique=True,
|
username = models.CharField(_("username"), max_length=32, unique=True,
|
||||||
help_text=_("Required. 64 characters or fewer. Letters, digits and ./-/_ only."),
|
help_text=_("Required. 32 characters or fewer. Letters, digits and ./-/_ only."),
|
||||||
validators=[validators.validate_username])
|
validators=[validators.validate_username])
|
||||||
password = models.CharField(_("password"), max_length=128)
|
password = models.CharField(_("password"), max_length=128)
|
||||||
account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
|
account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
|
||||||
|
|
|
@ -7,7 +7,6 @@ def html_to_pdf(html, pagination=False):
|
||||||
""" converts HTL to PDF using wkhtmltopdf """
|
""" converts HTL to PDF using wkhtmltopdf """
|
||||||
context = {
|
context = {
|
||||||
'pagination': textwrap.dedent("""\
|
'pagination': textwrap.dedent("""\
|
||||||
--footer-center "Page [page] of [topage]"\\
|
|
||||||
--footer-center "Page [page] of [topage]" \\
|
--footer-center "Page [page] of [topage]" \\
|
||||||
--footer-font-name sans \\
|
--footer-font-name sans \\
|
||||||
--footer-font-size 7 \\
|
--footer-font-size 7 \\
|
||||||
|
@ -20,6 +19,6 @@ def html_to_pdf(html, pagination=False):
|
||||||
--use-xserver \\
|
--use-xserver \\
|
||||||
%(pagination)s \\
|
%(pagination)s \\
|
||||||
--margin-bottom 22 \\
|
--margin-bottom 22 \\
|
||||||
--margin-top 20 - -\
|
--margin-top 20 - - \
|
||||||
""") % context
|
""") % context
|
||||||
return run(cmd, stdin=html.encode('utf-8')).stdout
|
return run(cmd, stdin=html.encode('utf-8')).stdout
|
||||||
|
|
|
@ -15,8 +15,6 @@ def render_email_template(template, context):
|
||||||
"""
|
"""
|
||||||
if isinstance(context, dict):
|
if isinstance(context, dict):
|
||||||
context = Context(context)
|
context = Context(context)
|
||||||
if isinstance(to, str):
|
|
||||||
to = [to]
|
|
||||||
|
|
||||||
if not 'site' in context:
|
if not 'site' in context:
|
||||||
from orchestra import settings
|
from orchestra import settings
|
||||||
|
@ -32,6 +30,8 @@ def render_email_template(template, context):
|
||||||
|
|
||||||
|
|
||||||
def send_email_template(template, context, to, email_from=None, html=None, attachments=[]):
|
def send_email_template(template, context, to, email_from=None, html=None, attachments=[]):
|
||||||
|
if isinstance(to, str):
|
||||||
|
to = [to]
|
||||||
subject, message = render_email_template(template, context)
|
subject, message = render_email_template(template, context)
|
||||||
msg = EmailMultiAlternatives(subject, message, email_from, to, attachments=attachments)
|
msg = EmailMultiAlternatives(subject, message, email_from, to, attachments=attachments)
|
||||||
if html:
|
if html:
|
||||||
|
|
|
@ -10,7 +10,7 @@ celery==3.1.16
|
||||||
kombu==3.0.23
|
kombu==3.0.23
|
||||||
billiard==3.3.0.18
|
billiard==3.3.0.18
|
||||||
Markdown==2.4
|
Markdown==2.4
|
||||||
djangorestframework==3.1.1
|
djangorestframework==3.1.2
|
||||||
ecdsa==0.11
|
ecdsa==0.11
|
||||||
Pygments==1.6
|
Pygments==1.6
|
||||||
django-filter==0.7
|
django-filter==0.7
|
||||||
|
|
Loading…
Reference in New Issue