YOUR
LOGO
HERE
@@ -76,8 +76,8 @@
{% for line in bill.lines.all %}
{{ line.id }}
{{ line.description }}
-
{{ line.amount }}
-
{{ line.rate }}
+
{{ line.amount|default:" " }}
+
{% if line.rate %}{{ line.rate }} &{{ currency.lower }};{% else %} {% endif %}
{{ line.price }} &{{ currency.lower }};
{% endfor %}
diff --git a/orchestra/apps/mails/admin.py b/orchestra/apps/mails/admin.py
index 9817ab89..7100cf2a 100644
--- a/orchestra/apps/mails/admin.py
+++ b/orchestra/apps/mails/admin.py
@@ -70,7 +70,8 @@ class MailboxAdmin(AccountAdminMixin, ExtendedModelAdmin):
add_url += '?account=%d&mailboxes=%s' % (account.pk, mailbox.pk)
img = '
'
onclick = 'onclick="return showAddAnotherPopup(this);"'
- add_link = '
%s Add address' % (add_url, onclick, img)
+ add_link = '
{img} Add address'.format(
+ add_url=add_url, onclick=onclick, img=img)
value = '%s
' % add_link
for pk, name, domain in mailbox.addresses.values_list('pk', 'name', 'domain__name'):
url = reverse('admin:mails_address_change', args=(pk,))
diff --git a/orchestra/apps/orders/models.py b/orchestra/apps/orders/models.py
index 256fcc21..81fe2c93 100644
--- a/orchestra/apps/orders/models.py
+++ b/orchestra/apps/orders/models.py
@@ -282,6 +282,9 @@ class Order(models.Model):
if service.handler.matches(instance):
if not orders:
account_id = getattr(instance, 'account_id', instance.pk)
+ if account_id is None:
+ # New account workaround -> user.account_id == None
+ continue
order = cls.objects.create(content_object=instance,
service=service, account_id=account_id)
else:
diff --git a/orchestra/apps/payments/actions.py b/orchestra/apps/payments/actions.py
index 83295b4d..90e2606c 100644
--- a/orchestra/apps/payments/actions.py
+++ b/orchestra/apps/payments/actions.py
@@ -1,5 +1,4 @@
-from .methods import BankTransfer
-
def process_transactions(modeladmin, request, queryset):
- BankTransfer().process(queryset)
+ from .methods import SEPADirectDebit
+ SEPADirectDebit().process(queryset)
diff --git a/orchestra/apps/payments/admin.py b/orchestra/apps/payments/admin.py
index f69cebe5..1bfeb0fe 100644
--- a/orchestra/apps/payments/admin.py
+++ b/orchestra/apps/payments/admin.py
@@ -6,7 +6,7 @@ from orchestra.admin.utils import admin_colored, admin_link
from orchestra.apps.accounts.admin import AccountAdminMixin
from .actions import process_transactions
-from .methods import BankTransfer
+from .methods import SEPADirectDebit
from .models import PaymentSource, Transaction, PaymentProcess
@@ -39,7 +39,7 @@ class TransactionAdmin(admin.ModelAdmin):
class PaymentSourceAdmin(AccountAdminMixin, admin.ModelAdmin):
list_display = ('label', 'method', 'number', 'account_link', 'is_active')
list_filter = ('method', 'is_active')
- form = BankTransfer().get_form()
+ form = SEPADirectDebit().get_form()
# TODO select payment source method
diff --git a/orchestra/apps/payments/methods/__init__.py b/orchestra/apps/payments/methods/__init__.py
index 589e72a0..e4da67fe 100644
--- a/orchestra/apps/payments/methods/__init__.py
+++ b/orchestra/apps/payments/methods/__init__.py
@@ -1,3 +1,3 @@
from .creditcard import CreditCard
-from .banktransfer import BankTransfer
+from .sepadirectdebit import SEPADirectDebit
from .options import PaymentMethod, PaymentSourceDataForm
diff --git a/orchestra/apps/payments/methods/banktransfer.py b/orchestra/apps/payments/methods/sepadirectdebit.py
similarity index 97%
rename from orchestra/apps/payments/methods/banktransfer.py
rename to orchestra/apps/payments/methods/sepadirectdebit.py
index 13392c83..7b301124 100644
--- a/orchestra/apps/payments/methods/banktransfer.py
+++ b/orchestra/apps/payments/methods/sepadirectdebit.py
@@ -15,26 +15,26 @@ from .. import settings
from .options import PaymentSourceDataForm, PaymentMethod
-class BankTransferForm(PaymentSourceDataForm):
+class SEPADirectDebitForm(PaymentSourceDataForm):
iban = IBANFormField(label='IBAN',
widget=forms.TextInput(attrs={'size': '50'}))
name = forms.CharField(max_length=128, label=_("Name"),
widget=forms.TextInput(attrs={'size': '50'}))
-class BankTransferSerializer(serializers.Serializer):
+class SEPADirectDebitSerializer(serializers.Serializer):
iban = serializers.CharField(label='IBAN', validators=[IBANValidator()],
min_length=min(IBAN_COUNTRY_CODE_LENGTH.values()), max_length=34)
name = serializers.CharField(label=_("Name"), max_length=128)
-class BankTransfer(PaymentMethod):
- verbose_name = _("Bank transfer")
+class SEPADirectDebit(PaymentMethod):
+ verbose_name = _("Direct Debit")
label_field = 'name'
number_field = 'iban'
process_credit = True
- form = BankTransferForm
- serializer = BankTransferSerializer
+ form = SEPADirectDebitForm
+ serializer = SEPADirectDebitSerializer
def process(self, transactions):
debts = []
diff --git a/orchestra/apps/payments/models.py b/orchestra/apps/payments/models.py
index bcc266f4..1c606c89 100644
--- a/orchestra/apps/payments/models.py
+++ b/orchestra/apps/payments/models.py
@@ -72,7 +72,7 @@ class Transaction(models.Model):
return "Transaction {}".format(self.id)
-# TODO rename to TransactionProcess
+# TODO rename to TransactionProcess or PaymentRequest TransactionRequest
class PaymentProcess(models.Model):
"""
Stores arbitrary data generated by payment methods while processing transactions
diff --git a/orchestra/bin/orchestra-admin b/orchestra/bin/orchestra-admin
index 56d1f16b..5a7292e2 100755
--- a/orchestra/bin/orchestra-admin
+++ b/orchestra/bin/orchestra-admin
@@ -127,7 +127,9 @@ function install_requirements () {
bind9utils \
python-cracklib \
libxml2-dev \
- libxslt1-dev"
+ libxslt1-dev \
+ wkhtmltopdf \
+ xvfb"
PIP="django==1.6.1 \
django-celery-email==1.0.4 \
@@ -151,8 +153,7 @@ function install_requirements () {
if $testing; then
APT="${APT} \
- iceweasel \
- xvfb"
+ iceweasel"
PIP="${PIP} \
selenium \
xvfbwrapper"
diff --git a/orchestra/utils/system.py b/orchestra/utils/system.py
index 9ff0e4f9..81b58237 100644
--- a/orchestra/utils/system.py
+++ b/orchestra/utils/system.py
@@ -46,21 +46,20 @@ def read_async(fd):
return ''
-def run(command, display=True, error_codes=[0], silent=True):
+def run(command, display=True, error_codes=[0], silent=True, stdin=''):
""" Subprocess wrapper for running commands """
if display:
sys.stderr.write("\n\033[1m $ %s\033[0m\n" % command)
- out_stream = subprocess.PIPE
- err_stream = subprocess.PIPE
p = subprocess.Popen(command, shell=True, executable='/bin/bash',
- stdout=out_stream, stderr=err_stream)
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
make_async(p.stdout)
make_async(p.stderr)
stdout = str()
stderr = str()
-
+ p.stdin.write(stdin)
+ p.stdin.close()
# Async reading of stdout and sterr
while True:
# Wait for data to become available