Fixes on bills and implemented domains serializer create() and update()
This commit is contained in:
parent
fd8d805b5e
commit
1223ed85e6
3
TODO.md
3
TODO.md
|
@ -412,5 +412,4 @@ touch /tmp/somefile
|
|||
# batch zone edditing
|
||||
# inherit registers from parent?
|
||||
|
||||
# Bill metric disk 5 GB: unialber: include not include 5, unialbert recheck period
|
||||
|
||||
# Disable pagination on membership fees (allways one page)
|
||||
|
|
|
@ -32,7 +32,7 @@ def download_bills(modeladmin, request, queryset):
|
|||
response['Content-Disposition'] = 'attachment; filename="orchestra-bills.zip"'
|
||||
return response
|
||||
bill = queryset.get()
|
||||
pdf = html_to_pdf(bill.html or bill.render())
|
||||
pdf = html_to_pdf(bill.html or bill.render(), pagination=bill.has_multiple_pages)
|
||||
return HttpResponse(pdf, content_type='application/pdf')
|
||||
download_bills.verbose_name = _("Download")
|
||||
download_bills.url_name = 'download'
|
||||
|
@ -78,9 +78,13 @@ def close_bills(modeladmin, request, queryset):
|
|||
else:
|
||||
url = reverse('admin:transactions_transaction_changelist')
|
||||
url += 'id__in=%s' % ','.join(map(str, transactions))
|
||||
context = {
|
||||
'url': url,
|
||||
'num': num,
|
||||
}
|
||||
message = ungettext(
|
||||
_('<a href="%s">One related transaction</a> has been created') % url,
|
||||
_('<a href="%s">%i related transactions</a> have been created') % (url, num),
|
||||
_('<a href="%(url)s">One related transaction</a> has been created') % context,
|
||||
_('<a href="%(url)s">%(num)i related transactions</a> have been created') % context,
|
||||
num)
|
||||
messages.success(request, mark_safe(message))
|
||||
return
|
||||
|
@ -105,12 +109,22 @@ close_bills.url_name = 'close'
|
|||
|
||||
|
||||
def send_bills(modeladmin, request, queryset):
|
||||
num = 0
|
||||
for bill in queryset:
|
||||
if not validate_contact(request, bill):
|
||||
return
|
||||
for bill in queryset:
|
||||
num += 1
|
||||
if num == 1:
|
||||
bill.send()
|
||||
else:
|
||||
# Batch email
|
||||
queryset.send()
|
||||
for bill in queryset:
|
||||
modeladmin.log_change(request, bill, 'Sent')
|
||||
messages.success(request, ungetetx(
|
||||
_("One bill has been sent."),
|
||||
_("%i bills have been sent.") % num,
|
||||
num))
|
||||
send_bills.verbose_name = lambda bill: _("Resend" if getattr(bill, 'is_sent', False) else "Send")
|
||||
send_bills.url_name = 'send'
|
||||
|
||||
|
@ -153,7 +167,7 @@ def undo_billing(modeladmin, request, queryset):
|
|||
else:
|
||||
# First iteration
|
||||
if order.billed_on < line.start_on:
|
||||
messages.error(request, "billed on is smaller than first line start_on.")
|
||||
messages.error(request, "Billed on is smaller than first line start_on.")
|
||||
return
|
||||
prev = line.end_on
|
||||
nlines += 1
|
||||
|
@ -168,6 +182,7 @@ def undo_billing(modeladmin, request, queryset):
|
|||
for line in lines:
|
||||
nlines += 1
|
||||
line.delete()
|
||||
# TODO update order history undo billing
|
||||
order.save(update_fields=('billed_until', 'billed_on'))
|
||||
norders += 1
|
||||
|
||||
|
@ -177,29 +192,14 @@ def undo_billing(modeladmin, request, queryset):
|
|||
})
|
||||
|
||||
|
||||
# TODO son't check for account equality
|
||||
def move_lines(modeladmin, request, queryset):
|
||||
def move_lines(modeladmin, request, queryset, action=None):
|
||||
# Validate
|
||||
account = None
|
||||
for line in queryset.select_related('bill'):
|
||||
bill = line.bill
|
||||
if not bill.is_open:
|
||||
messages.error(request, _("Can not move lines from a closed bill."))
|
||||
return
|
||||
elif not account:
|
||||
account = bill.account
|
||||
elif bill.account != account:
|
||||
messages.error(request, _("Can not move lines from different accounts"))
|
||||
return
|
||||
target = request.GET.get('target')
|
||||
if not target:
|
||||
# select target
|
||||
context = {}
|
||||
return render(request, 'admin/orchestra/generic_confirmation.html', context)
|
||||
target = Bill.objects.get(pk=int(pk))
|
||||
if target.account != account:
|
||||
messages.error(request, _("Target account different than lines account."))
|
||||
return
|
||||
if request.POST.get('post') == 'generic_confirmation':
|
||||
for line in queryset:
|
||||
line.bill = target
|
||||
|
@ -212,9 +212,4 @@ def move_lines(modeladmin, request, queryset):
|
|||
|
||||
def copy_lines(modeladmin, request, queryset):
|
||||
# same as move, but changing action behaviour
|
||||
pass
|
||||
|
||||
|
||||
def delete_lines(modeladmin, request, queryset):
|
||||
# Call contrib.admin delete action if all lines in open bill
|
||||
pass
|
||||
return move_lines(modeladmin, request, queryset)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django import forms
|
||||
from django.conf.urls import url
|
||||
from django.contrib import admin
|
||||
from django.contrib import admin, messages
|
||||
from django.contrib.admin.utils import unquote
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
|
@ -9,6 +9,7 @@ from django.db.models.functions import Coalesce
|
|||
from django.templatetags.static import static
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.utils import admin_date, insertattr, admin_link
|
||||
|
@ -101,16 +102,22 @@ class ClosedBillLineInline(BillLineInline):
|
|||
|
||||
class BillLineAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'description', 'bill_link', 'rate', 'quantity', 'tax', 'subtotal', 'display_sublinetotal',
|
||||
'display_total'
|
||||
'description', 'bill_link', 'display_is_open', 'account_link', 'rate', 'quantity', 'tax',
|
||||
'subtotal', 'display_sublinetotal', 'display_total'
|
||||
)
|
||||
actions = (actions.undo_billing, actions.move_lines, actions.copy_lines,)
|
||||
list_filter = ('tax', ('bill', admin.RelatedOnlyFieldListFilter))
|
||||
list_filter = ('tax', ('bill', admin.RelatedOnlyFieldListFilter), 'bill__is_open')
|
||||
list_select_related = ('bill',)
|
||||
search_fields = ('description', 'bill__number')
|
||||
|
||||
account_link = admin_link('bill__account')
|
||||
bill_link = admin_link('bill')
|
||||
|
||||
def display_is_open(self, instance):
|
||||
return instance.bill.is_open
|
||||
display_is_open.short_description = _("Is open")
|
||||
display_is_open.boolean = True
|
||||
|
||||
def display_sublinetotal(self, instance):
|
||||
return instance.subline_total or ''
|
||||
display_sublinetotal.short_description = _("Subline")
|
||||
|
@ -140,18 +147,26 @@ class BillLineManagerAdmin(BillLineAdmin):
|
|||
return qset
|
||||
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
GET = request.GET.copy()
|
||||
bill_ids = GET.pop('ids', None)
|
||||
GET_copy = request.GET.copy()
|
||||
bill_ids = GET_copy.pop('ids', None)
|
||||
if bill_ids:
|
||||
request.GET = GET
|
||||
bill_ids = list(map(int, bill_ids))
|
||||
bill_ids = bill_ids[0]
|
||||
request.GET = GET_copy
|
||||
bill_ids = list(map(int, bill_ids.split(',')))
|
||||
else:
|
||||
messages.error(request, _("No bills selected."))
|
||||
return redirect('..')
|
||||
self.bill_ids = bill_ids
|
||||
if bill_ids and len(bill_ids) == 1:
|
||||
if len(bill_ids) == 1:
|
||||
bill_url = reverse('admin:bills_bill_change', args=(bill_ids[0],))
|
||||
bill = Bill.objects.get(pk=bill_ids[0])
|
||||
bill_link = '<a href="%s">%s</a>' % (bill_url, bill.number)
|
||||
title = mark_safe(_("Manage %s bill lines.") % bill_link)
|
||||
if not bill.is_open:
|
||||
messages.warning(request, _("Bill not in open state."))
|
||||
else:
|
||||
if Bill.objects.filter(id__in=bill_ids, is_open=False).exists():
|
||||
messages.warning(request, _("Not all bills are in open state."))
|
||||
title = _("Manage bill lines of multiple bills.")
|
||||
context = {
|
||||
'title': title,
|
||||
|
@ -177,13 +192,15 @@ class BillAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
'fields': ('html',),
|
||||
}),
|
||||
)
|
||||
list_prefetch_related = ('transactions',)
|
||||
search_fields = ('number', 'account__username', 'comments')
|
||||
change_view_actions = [
|
||||
actions.manage_lines, actions.view_bill, actions.download_bills, actions.send_bills,
|
||||
actions.close_bills
|
||||
]
|
||||
list_prefetch_related = ('transactions',)
|
||||
search_fields = ('number', 'account__username', 'comments')
|
||||
actions = [actions.download_bills, actions.close_bills, actions.send_bills]
|
||||
actions = [
|
||||
actions.manage_lines, actions.download_bills, actions.close_bills, actions.send_bills
|
||||
]
|
||||
change_readonly_fields = ('account_link', 'type', 'is_open')
|
||||
readonly_fields = ('number', 'display_total', 'is_sent', 'display_payment_state')
|
||||
inlines = [BillLineInline, ClosedBillLineInline]
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-05-27 13:28+0000\n"
|
||||
"POT-Creation-Date: 2015-05-28 09:23+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"
|
||||
|
@ -34,97 +34,114 @@ msgstr ""
|
|||
msgid "Selected bills have been closed"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:82
|
||||
#: actions.py:86
|
||||
#, python-format
|
||||
msgid "<a href=\"%s\">One related transaction</a> has been created"
|
||||
msgid "<a href=\"%(url)s\">One related transaction</a> has been created"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:83
|
||||
#: actions.py:87
|
||||
#, python-format
|
||||
msgid "<a href=\"%s\">%i related transactions</a> have been created"
|
||||
msgid "<a href=\"%(url)s\">%(num)i related transactions</a> have been created"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:89
|
||||
#: actions.py:93
|
||||
msgid "Are you sure about closing the following bills?"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:90
|
||||
#: actions.py:94
|
||||
msgid ""
|
||||
"Once a bill is closed it can not be further modified.</p><p>Please select a "
|
||||
"payment source for the selected bills"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:103
|
||||
#: actions.py:107
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:114
|
||||
#: actions.py:125
|
||||
msgid "One bill has been sent."
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:126
|
||||
#, python-format
|
||||
msgid "%i bills have been sent."
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:128
|
||||
msgid "Resend"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:174
|
||||
#: actions.py:189
|
||||
#, python-format
|
||||
msgid "%(norders)s orders and %(nlines)s lines undoed."
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:187
|
||||
msgid "Can not move lines from a closed bill."
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:192
|
||||
msgid "Can not move lines from different accounts"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:201
|
||||
msgid "Target account different than lines account."
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:208
|
||||
msgid "Lines moved"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:48 admin.py:92 admin.py:121 forms.py:11
|
||||
#: admin.py:49 admin.py:93 admin.py:128 forms.py:11
|
||||
msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:79
|
||||
#: admin.py:80
|
||||
msgid "Description"
|
||||
msgstr "Descripció"
|
||||
|
||||
#: admin.py:87
|
||||
#: admin.py:88
|
||||
msgid "Subtotal"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:116
|
||||
#: admin.py:118
|
||||
msgid "Is open"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:123
|
||||
msgid "Subline"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:153
|
||||
#: admin.py:157
|
||||
msgid "No bills selected."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:164
|
||||
#, python-format
|
||||
msgid "Manage %s bill lines."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:155
|
||||
#: admin.py:166
|
||||
msgid "Bill not in open state."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:169
|
||||
msgid "Not all bills are in open state."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:170
|
||||
msgid "Manage bill lines of multiple bills."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:175
|
||||
#: admin.py:190
|
||||
msgid "Raw"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:196
|
||||
#: admin.py:208
|
||||
msgid "Created"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:213
|
||||
msgid "lines"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:201 templates/bills/microspective.html:118
|
||||
#: admin.py:218 templates/bills/microspective.html:118
|
||||
msgid "total"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:209 models.py:88 models.py:340
|
||||
#: admin.py:226 models.py:88 models.py:352
|
||||
msgid "type"
|
||||
msgstr "tipus"
|
||||
|
||||
#: admin.py:226
|
||||
#: admin.py:243
|
||||
msgid "Payment"
|
||||
msgstr "Pagament"
|
||||
|
||||
|
@ -290,82 +307,78 @@ msgstr "comentaris"
|
|||
msgid "HTML"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:280
|
||||
#: models.py:285
|
||||
msgid "bill"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:281 models.py:338 templates/bills/microspective.html:73
|
||||
#: models.py:286 models.py:350 templates/bills/microspective.html:73
|
||||
msgid "description"
|
||||
msgstr "descripció"
|
||||
|
||||
#: models.py:282
|
||||
#: models.py:287
|
||||
msgid "rate"
|
||||
msgstr "tarifa"
|
||||
|
||||
#: models.py:283
|
||||
#: models.py:288
|
||||
msgid "quantity"
|
||||
msgstr "quantitat"
|
||||
|
||||
#: models.py:284
|
||||
#: models.py:289
|
||||
#, fuzzy
|
||||
#| msgid "quantity"
|
||||
msgid "Verbose quantity"
|
||||
msgstr "quantitat"
|
||||
|
||||
#: models.py:285 templates/bills/microspective.html:77
|
||||
#: models.py:290 templates/bills/microspective.html:77
|
||||
#: templates/bills/microspective.html:111
|
||||
msgid "subtotal"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:286
|
||||
#: models.py:291
|
||||
msgid "tax"
|
||||
msgstr "impostos"
|
||||
|
||||
#: models.py:287
|
||||
#: models.py:292
|
||||
msgid "start"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:288
|
||||
#: models.py:293
|
||||
msgid "end"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:290
|
||||
#: models.py:295
|
||||
msgid "Informative link back to the order"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:291
|
||||
#: models.py:296
|
||||
msgid "order billed"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:292
|
||||
#: models.py:297
|
||||
msgid "order billed until"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:293
|
||||
#: models.py:298
|
||||
msgid "created"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:295
|
||||
#: models.py:300
|
||||
msgid "amended line"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:316
|
||||
msgid "{ini} to {end}"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:331
|
||||
#: models.py:343
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:332
|
||||
#: models.py:344
|
||||
msgid "Compensation"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:333
|
||||
#: models.py:345
|
||||
msgid "Other"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:337
|
||||
#: models.py:349
|
||||
msgid "bill line"
|
||||
msgstr ""
|
||||
|
||||
|
@ -378,20 +391,15 @@ msgstr ""
|
|||
msgid "On %(bank_account)s"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective-fee.html:113
|
||||
#: templates/bills/microspective-fee.html:114
|
||||
#, python-format
|
||||
msgid "From %(period)s"
|
||||
msgid "From %(ini)s to %(end)s"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective-fee.html:118
|
||||
#: templates/bills/microspective-fee.html:121
|
||||
msgid ""
|
||||
"\n"
|
||||
"<strong>Con vuestras cuotas</strong>, ademas de obtener conexion y multitud "
|
||||
"de servicios, estais<br>\n"
|
||||
" Con vuestras cuotas, ademas de obtener conexion y multitud de servicios,"
|
||||
"<br>\n"
|
||||
" Con vuestras cuotas, ademas de obtener conexion <br>\n"
|
||||
" Con vuestras cuotas, ademas de obtener <br>\n"
|
||||
"<strong>With your membership</strong> you are supporting ...\n"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:49
|
||||
|
@ -403,8 +411,9 @@ msgid "TOTAL"
|
|||
msgstr "TOTAL"
|
||||
|
||||
#: templates/bills/microspective.html:57
|
||||
#, python-format
|
||||
msgid "%(bill_type|upper)s DATE "
|
||||
#, fuzzy, python-format
|
||||
#| msgid "%(bill_type|upper)s DATE "
|
||||
msgid "%(bill_type)s DATE"
|
||||
msgstr "DATA %(bill_type|upper)s"
|
||||
|
||||
#: templates/bills/microspective.html:74
|
||||
|
@ -437,10 +446,18 @@ msgid "PAYMENT"
|
|||
msgstr "PAGAMENT"
|
||||
|
||||
#: templates/bills/microspective.html:140
|
||||
#, python-format
|
||||
#, 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 ""
|
||||
"\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"
|
||||
" Please make sure to state your name and the <i>%(type)s</"
|
||||
"i> number.\n"
|
||||
" Our bank account number is <br>\n"
|
||||
|
@ -459,8 +476,8 @@ msgstr "PREGUNTES"
|
|||
msgid ""
|
||||
"\n"
|
||||
" If you have any question about your <i>%(type)s</i>, please\n"
|
||||
" feel free to contact us at your convinience. We will reply as "
|
||||
"soon as we get\n"
|
||||
" feel free to write us at %(email)s. We will reply as soon as we "
|
||||
"get\n"
|
||||
" your message.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
|
469
orchestra/contrib/bills/locale/es/LC_MESSAGES/django.po
Normal file
469
orchestra/contrib/bills/locale/es/LC_MESSAGES/django.po
Normal file
|
@ -0,0 +1,469 @@
|
|||
# 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 09:23+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:37
|
||||
msgid "Download"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:47
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:55
|
||||
msgid "Selected bills should be in open state"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:73
|
||||
msgid "Selected bills have been closed"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:86
|
||||
#, python-format
|
||||
msgid "<a href=\"%(url)s\">One related transaction</a> has been created"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:87
|
||||
#, python-format
|
||||
msgid "<a href=\"%(url)s\">%(num)i related transactions</a> have been created"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:93
|
||||
msgid "Are you sure about closing the following bills?"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:94
|
||||
msgid ""
|
||||
"Once a bill is closed it can not be further modified.</p><p>Please select a "
|
||||
"payment source for the selected bills"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:107
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:125
|
||||
msgid "One bill has been sent."
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:126
|
||||
#, python-format
|
||||
msgid "%i bills have been sent."
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:128
|
||||
msgid "Resend"
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:189
|
||||
#, python-format
|
||||
msgid "%(norders)s orders and %(nlines)s lines undoed."
|
||||
msgstr ""
|
||||
|
||||
#: actions.py:208
|
||||
msgid "Lines moved"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:49 admin.py:93 admin.py:128 forms.py:11
|
||||
msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:80
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:88
|
||||
msgid "Subtotal"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:118
|
||||
msgid "Is open"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:123
|
||||
msgid "Subline"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:157
|
||||
msgid "No bills selected."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:164
|
||||
#, python-format
|
||||
msgid "Manage %s bill lines."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:166
|
||||
msgid "Bill not in open state."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:169
|
||||
msgid "Not all bills are in open state."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:170
|
||||
msgid "Manage bill lines of multiple bills."
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:190
|
||||
msgid "Raw"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:208
|
||||
msgid "Created"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:213
|
||||
msgid "lines"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:218 templates/bills/microspective.html:118
|
||||
msgid "total"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:226 models.py:88 models.py:352
|
||||
msgid "type"
|
||||
msgstr ""
|
||||
|
||||
#: admin.py:243
|
||||
msgid "Payment"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:17
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:18 models.py:78
|
||||
msgid "Invoice"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:19 models.py:79
|
||||
msgid "Amendment invoice"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:20 models.py:80
|
||||
msgid "Fee"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:21
|
||||
msgid "Amendment fee"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:22
|
||||
msgid "Pro-forma"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:41
|
||||
msgid "positive price"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:46 filters.py:64
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:47 filters.py:65
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
#: filters.py:59
|
||||
msgid "has bill contact"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:9
|
||||
msgid "Number"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:10
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:12
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:13
|
||||
msgid "Source"
|
||||
msgstr ""
|
||||
|
||||
#: helpers.py:10
|
||||
msgid ""
|
||||
"{relation} account \"{account}\" does not have a declared invoice contact. "
|
||||
"You should <a href=\"{url}#invoicecontact-group\">provide one</a>"
|
||||
msgstr ""
|
||||
|
||||
#: helpers.py:17
|
||||
msgid "Related"
|
||||
msgstr ""
|
||||
|
||||
#: helpers.py:24
|
||||
msgid "Main"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:23 models.py:86
|
||||
msgid "account"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:25
|
||||
msgid "name"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:26
|
||||
msgid "Account full name will be used when left blank."
|
||||
msgstr ""
|
||||
|
||||
#: models.py:27
|
||||
msgid "address"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:28
|
||||
msgid "city"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:30
|
||||
msgid "zip code"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:31
|
||||
msgid "Enter a valid zipcode."
|
||||
msgstr ""
|
||||
|
||||
#: models.py:32
|
||||
msgid "country"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:35
|
||||
msgid "VAT number"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:67
|
||||
msgid "Paid"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:68
|
||||
msgid "Pending"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:69
|
||||
msgid "Bad debt"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:81
|
||||
msgid "Amendment Fee"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:82
|
||||
msgid "Pro forma"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:85
|
||||
msgid "number"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:89
|
||||
msgid "created on"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:90
|
||||
msgid "closed on"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:91
|
||||
msgid "open"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:92
|
||||
msgid "sent"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:93
|
||||
msgid "due on"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:94
|
||||
msgid "updated on"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:97
|
||||
msgid "comments"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:98
|
||||
msgid "HTML"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:285
|
||||
msgid "bill"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:286 models.py:350 templates/bills/microspective.html:73
|
||||
msgid "description"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:287
|
||||
msgid "rate"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:288
|
||||
msgid "quantity"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:289
|
||||
msgid "Verbose quantity"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:290 templates/bills/microspective.html:77
|
||||
#: templates/bills/microspective.html:111
|
||||
msgid "subtotal"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:291
|
||||
msgid "tax"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:292
|
||||
msgid "start"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:293
|
||||
msgid "end"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:295
|
||||
msgid "Informative link back to the order"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:296
|
||||
msgid "order billed"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:297
|
||||
msgid "order billed until"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:298
|
||||
msgid "created"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:300
|
||||
msgid "amended line"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:343
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:344
|
||||
msgid "Compensation"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:345
|
||||
msgid "Other"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:349
|
||||
msgid "bill line"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective-fee.html:107
|
||||
msgid "Due date"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective-fee.html:108
|
||||
#, python-format
|
||||
msgid "On %(bank_account)s"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective-fee.html:114
|
||||
#, python-format
|
||||
msgid "From %(ini)s to %(end)s"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective-fee.html:121
|
||||
msgid ""
|
||||
"\n"
|
||||
"<strong>With your membership</strong> you are supporting ...\n"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:49
|
||||
msgid "DUE DATE"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:53
|
||||
msgid "TOTAL"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:57
|
||||
#, python-format
|
||||
msgid "%(bill_type)s DATE"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:74
|
||||
msgid "period"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:75
|
||||
msgid "hrs/qty"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:76
|
||||
msgid "rate/price"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:111
|
||||
#: templates/bills/microspective.html:114
|
||||
msgid "VAT"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:114
|
||||
msgid "taxes"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:130
|
||||
msgid "COMMENTS"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:136
|
||||
msgid "PAYMENT"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:140
|
||||
#, 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"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:149
|
||||
msgid "QUESTIONS"
|
||||
msgstr ""
|
||||
|
||||
#: templates/bills/microspective.html:150
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" If you have any question about your <i>%(type)s</i>, please\n"
|
||||
" feel free to write us at %(email)s. We will reply as soon as we "
|
||||
"get\n"
|
||||
" your message.\n"
|
||||
" "
|
||||
msgstr ""
|
|
@ -124,6 +124,10 @@ class Bill(models.Model):
|
|||
return self.PENDING
|
||||
return self.BAD_DEBT
|
||||
|
||||
@property
|
||||
def has_multiple_pages(self):
|
||||
return self.type != self.FEE
|
||||
|
||||
def get_payment_state_display(self):
|
||||
value = self.payment_state
|
||||
return force_text(dict(self.PAYMENT_STATES).get(value, value))
|
||||
|
@ -186,6 +190,7 @@ class Bill(models.Model):
|
|||
|
||||
def send(self):
|
||||
html = self.html or self.render()
|
||||
pdf = html_to_pdf(html, pagination=self.has_multiple_pages)
|
||||
self.account.send_email(
|
||||
template=settings.BILLS_EMAIL_NOTIFICATION_TEMPLATE,
|
||||
context={
|
||||
|
@ -195,7 +200,7 @@ class Bill(models.Model):
|
|||
email_from=settings.BILLS_SELLER_EMAIL,
|
||||
contacts=(Contact.BILLING,),
|
||||
attachments=[
|
||||
('%s.pdf' % self.number, html_to_pdf(html), 'application/pdf')
|
||||
('%s.pdf' % self.number, pdf, 'application/pdf')
|
||||
]
|
||||
)
|
||||
self.is_sent = True
|
||||
|
@ -312,12 +317,10 @@ class BillLine(models.Model):
|
|||
if self.start_on.day != 1 or self.end_on.day != 1:
|
||||
date_format = "N j, 'y"
|
||||
end = date(self.end_on, date_format)
|
||||
# .strftime(date_format)
|
||||
else:
|
||||
end = date((self.end_on - datetime.timedelta(days=1)), date_format)
|
||||
# ).strftime(date_format)
|
||||
ini = date(self.start_on, date_format)
|
||||
#.strftime(date_format)
|
||||
ini = date(self.start_on, date_format).capitalize()
|
||||
end = end.capitalize()
|
||||
if not self.end_on:
|
||||
return ini
|
||||
if ini == end:
|
||||
|
|
|
@ -99,30 +99,31 @@ hr {
|
|||
<div id="number" class="column-1">
|
||||
<span id="number-title">{% filter title %}{% trans bill.get_type_display %}{% endfilter %}</span><br>
|
||||
<span id="number-value">{{ bill.number }}</span><br>
|
||||
<span id="number-date">{{ bill.closed_on | default:now | date | capfirst }}</span><br>
|
||||
<span id="number-date">{{ bill.closed_on | default:now | date:"F j, Y" | capfirst }}</span><br>
|
||||
</div>
|
||||
|
||||
<div id="amount" class="column-2">
|
||||
<span id="amount-value">{{ bill.get_total }} &{{ currency.lower }};</span><br>
|
||||
<span id="amount-note">{% trans "Due date" %} {{ payment.due_date| default:default_due_date | date }}<br>
|
||||
<span id="amount-note">{% trans "Due date" %} {{ payment.due_date| default:default_due_date | date:"F j, Y" }}<br>
|
||||
{% if not payment.message %}{% blocktrans with bank_account=seller_info.bank_account %}On {{ bank_account }}{% endblocktrans %}{% endif %}<br>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div id="date" class="column-2">
|
||||
{% blocktrans with period=bill.lines.get.get_verbose_period %}From {{ period }}{% endblocktrans %}
|
||||
{% with line=bill.lines.get %}
|
||||
{% blocktrans with ini=line.start_on|date:"F j, Y" end=line.end_on|date:"F j, Y" %}From {{ ini }} to {{ end }}{% endblocktrans %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="text">
|
||||
{% blocktrans %}
|
||||
<strong>Con vuestras cuotas</strong>, ademas de obtener conexion y multitud de servicios, estais<br>
|
||||
Con vuestras cuotas, ademas de obtener conexion y multitud de servicios,<br>
|
||||
Con vuestras cuotas, ademas de obtener conexion <br>
|
||||
Con vuestras cuotas, ademas de obtener <br>
|
||||
<strong>With your membership</strong> you are supporting ...
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
<hr>
|
||||
{{ block.super }}
|
||||
|
|
|
@ -175,12 +175,12 @@ a:hover {
|
|||
}
|
||||
|
||||
#lines .column-description {
|
||||
width: 42%;
|
||||
width: 40%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#lines .column-period {
|
||||
width: 20%;
|
||||
width: 22%;
|
||||
}
|
||||
|
||||
#lines .column-quantity {
|
||||
|
|
|
@ -47,15 +47,15 @@
|
|||
<hr>
|
||||
<div id="due-date">
|
||||
<span class="title">{% trans "DUE DATE" %}</span><br>
|
||||
<psan class="value">{{ bill.due_on | default:default_due_date | date }}</span>
|
||||
<psan class="value">{{ bill.due_on | default:default_due_date | date | capfirst }}</span>
|
||||
</div>
|
||||
<div id="total">
|
||||
<span class="title">{% trans "TOTAL" %}</span><br>
|
||||
<psan class="value">{{ bill.get_total }} &{{ currency.lower }};</span>
|
||||
</div>
|
||||
<div id="bill-date">
|
||||
<span class="title">{% blocktrans with bill_type=bill.get_type_display.upper %}{{ bill_type }} DATE {% endblocktrans %}</span><br>
|
||||
<psan class="value">{{ bill.closed_on | default:now | date }}</span>
|
||||
<span class="title">{% blocktrans with bill_type=bill.get_type_display.upper %}{{ bill_type }} DATE{% endblocktrans %}</span><br>
|
||||
<psan class="value">{{ bill.closed_on | default:now | date | capfirst }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="buyer-details">
|
||||
|
@ -77,9 +77,9 @@
|
|||
<span class="title column-subtotal">{% trans "subtotal" %}</span>
|
||||
<br>
|
||||
{% for line in lines %}
|
||||
{% with sublines=line.sublines.all description=line.description|slice:"40:" %}
|
||||
{% with sublines=line.sublines.all description=line.description|slice:"38:" %}
|
||||
<span class="{% if not sublines and not description %}last {% endif %}column-id">{% if not line.order_id %}L{% endif %}{{ line.order_id }}</span>
|
||||
<span class="{% if not sublines and not description %}last {% endif %}column-description">{{ line.description|slice:":40" }}</span>
|
||||
<span class="{% if not sublines and not description %}last {% endif %}column-description">{{ line.description|slice:":38" }}</span>
|
||||
<span class="{% if not sublines and not description %}last {% endif %}column-period">{{ line.get_verbose_period }}</span>
|
||||
<span class="{% if not sublines and not description %}last {% endif %}column-quantity">{{ line.get_verbose_quantity|default:" "|safe }}</span>
|
||||
<span class="{% if not sublines and not description %}last {% endif %}column-rate">{% if line.rate %}{{ line.rate }} &{{ currency.lower }};{% else %} {% endif %}</span>
|
||||
|
@ -87,7 +87,7 @@
|
|||
<br>
|
||||
{% if description %}
|
||||
<span class="{% if not sublines %}last {% endif %}subline column-id"> </span>
|
||||
<span class="{% if not sublines %}last {% endif %}subline column-description">{{ description|truncatechars:41 }}</span>
|
||||
<span class="{% if not sublines %}last {% endif %}subline column-description">{{ description|truncatechars:39 }}</span>
|
||||
<span class="{% if not sublines %}last {% endif %}subline column-period"> </span>
|
||||
<span class="{% if not sublines %}last {% endif %}subline column-quantity"> </span>
|
||||
<span class="{% if not sublines %}last {% endif %}subline column-rate"> </span>
|
||||
|
@ -95,7 +95,7 @@
|
|||
{% endif %}
|
||||
{% for subline in sublines %}
|
||||
<span class="{% if forloop.last %}last {% endif %}subline column-id"> </span>
|
||||
<span class="{% if forloop.last %}last {% endif %}subline column-description">{{ subline.description|truncatechars:41 }}</span>
|
||||
<span class="{% if forloop.last %}last {% endif %}subline column-description">{{ subline.description|truncatechars:39 }}</span>
|
||||
<span class="{% if forloop.last %}last {% endif %}subline column-period"> </span>
|
||||
<span class="{% if forloop.last %}last {% endif %}subline column-quantity"> </span>
|
||||
<span class="{% if forloop.last %}last {% endif %}subline column-rate"> </span>
|
||||
|
@ -138,7 +138,7 @@
|
|||
{{ payment.message | safe }}
|
||||
{% else %}
|
||||
{% 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>
|
||||
Please make sure to state your name and the <i>{{ type }}</i> number.
|
||||
Our bank account number is <br>
|
||||
{% endblocktrans %}
|
||||
|
@ -147,9 +147,9 @@
|
|||
</div>
|
||||
<div id="questions">
|
||||
<span class="title">{% trans "QUESTIONS" %}</span>
|
||||
{% blocktrans with type=bill.get_type_display.lower %}
|
||||
{% blocktrans with type=bill.get_type_display.lower email=seller_info.email %}
|
||||
If you have any question about your <i>{{ type }}</i>, please
|
||||
feel free to contact us at your convinience. We will reply as soon as we get
|
||||
feel free to write us at {{ email }}. We will reply as soon as we get
|
||||
your message.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
|
|
|
@ -21,7 +21,7 @@ class RecordSerializer(serializers.ModelSerializer):
|
|||
|
||||
class DomainSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
|
||||
""" Validates if this zone generates a correct zone file """
|
||||
records = RecordSerializer(required=False, many=True) #allow_add_remove=True)
|
||||
records = RecordSerializer(required=False, many=True)
|
||||
|
||||
class Meta:
|
||||
model = Domain
|
||||
|
@ -44,3 +44,35 @@ class DomainSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
|
|||
domain = domain_for_validation(self.instance, records)
|
||||
validators.validate_zone(domain.render_zone())
|
||||
return data
|
||||
|
||||
def create(self, validated_data):
|
||||
records = validated_data.pop('records')
|
||||
domain = super(DomainSerializer, self).create(validated_data)
|
||||
for record in records:
|
||||
domain.records.create(type=record['type'], value=record['value'])
|
||||
return domain
|
||||
|
||||
def update(self, validated_data):
|
||||
precords = validated_data.pop('records')
|
||||
domain = super(DomainSerializer, self).update(validated_data)
|
||||
to_delete = []
|
||||
for erecord in domain.records.all():
|
||||
match = False
|
||||
for ix, precord in enumerate(precords):
|
||||
if erecord.type == precord['type'] and erecord.value == precord['value']:
|
||||
match = True
|
||||
break
|
||||
if match:
|
||||
precords.remove(ix)
|
||||
else:
|
||||
to_delete.append(erecord)
|
||||
for precord in precords:
|
||||
try:
|
||||
recycled = to_delete.pop()
|
||||
except IndexError:
|
||||
domain.records.create(type=precord['type'], value=precord['value'])
|
||||
else:
|
||||
recycled.type = precord['type']
|
||||
recycled.value = precord['value']
|
||||
recycled.save()
|
||||
return domain
|
||||
|
|
|
@ -92,7 +92,7 @@ class BillSelectedOrders(object):
|
|||
url = change_url(bills[0])
|
||||
else:
|
||||
url = reverse('admin:bills_bill_changelist')
|
||||
ids = ','.join(map(str, bills))
|
||||
ids = ','.join([str(b.id) for b in bills])
|
||||
url += '?id__in=%s' % ids
|
||||
msg = ungettext(
|
||||
'<a href="{url}">One bill</a> has been created.',
|
||||
|
|
|
@ -245,6 +245,10 @@ class ServiceHandler(plugins.Plugin, metaclass=plugins.PluginMount):
|
|||
}))
|
||||
|
||||
def generate_line(self, order, price, *dates, metric=1, discounts=None, computed=False):
|
||||
"""
|
||||
discounts: already applied discounts on price
|
||||
computed: price = price*size already performed
|
||||
"""
|
||||
if len(dates) == 2:
|
||||
ini, end = dates
|
||||
elif len(dates) == 1:
|
||||
|
@ -377,7 +381,8 @@ class ServiceHandler(plugins.Plugin, metaclass=plugins.PluginMount):
|
|||
size = self.get_price_size(order.new_billed_until, new_end)
|
||||
price += price*size
|
||||
order.new_billed_until = new_end
|
||||
line = self.generate_line(order, price, ini, new_end or end, discounts=discounts, computed=True)
|
||||
line = self.generate_line(
|
||||
order, price, ini, new_end or end, discounts=discounts, computed=True)
|
||||
lines.append(line)
|
||||
return lines
|
||||
|
||||
|
|
|
@ -3,17 +3,24 @@ import textwrap
|
|||
from orchestra.utils.sys import run
|
||||
|
||||
|
||||
def html_to_pdf(html):
|
||||
def html_to_pdf(html, pagination=False):
|
||||
""" converts HTL to PDF using wkhtmltopdf """
|
||||
return run(textwrap.dedent("""\
|
||||
PATH=$PATH:/usr/local/bin/
|
||||
xvfb-run -a -s "-screen 0 2480x3508x16" wkhtmltopdf -q \\
|
||||
--use-xserver \\
|
||||
print(pagination)
|
||||
context = {
|
||||
'pagination': textwrap.dedent("""\
|
||||
--footer-center "Page [page] of [topage]"\\
|
||||
--footer-center "Page [page] of [topage]" \\
|
||||
--footer-font-name sans \\
|
||||
--footer-font-size 7 \\
|
||||
--footer-spacing 7 \\
|
||||
--footer-spacing 7"""
|
||||
) if pagination else '',
|
||||
}
|
||||
cmd = textwrap.dedent("""\
|
||||
PATH=$PATH:/usr/local/bin/
|
||||
xvfb-run -a -s "-screen 0 2480x3508x16" wkhtmltopdf -q \\
|
||||
--use-xserver \\
|
||||
%(pagination)s \\
|
||||
--margin-bottom 22 \\
|
||||
--margin-top 20 - - """),
|
||||
stdin=html.encode('utf-8')
|
||||
).stdout
|
||||
--margin-top 20 - -\
|
||||
""") % context
|
||||
return run(cmd, stdin=html.encode('utf-8')).stdout
|
||||
|
|
Loading…
Reference in a new issue