Skip to content

Commit

Permalink
Refs #68 - Renamed ref_number/extra_infos variables
Browse files Browse the repository at this point in the history
  • Loading branch information
claudep committed Mar 30, 2022
1 parent ca496de commit d901682
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 37 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ ChangeLog
Unreleased
----------
- Replaced ``##`` with ``//`` as separator in additional informations (#75).
- Renamed ``--extra-infos`` command line parameter to ``--additional-information``
and renamed ``extra_infos`` and ``ref_number`` ``QRBill.__init__`` arguments
to ``additional_information`` and ``reference_number``, respectively.
The old arguments are still accepted but raise a deprecation warning (#68).

0.7.1 (2022-03-07)
------------------
Expand Down
62 changes: 39 additions & 23 deletions qrbill/bill.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re
import warnings
from datetime import date
from decimal import Decimal
from io import BytesIO
Expand Down Expand Up @@ -219,7 +220,8 @@ class QRBill:

def __init__(
self, account=None, creditor=None, final_creditor=None, amount=None,
currency='CHF', due_date=None, debtor=None, ref_number=None, extra_infos='',
currency='CHF', due_date=None, debtor=None, ref_number=None,
reference_number=None, extra_infos='', additional_information='',
alt_procs=(), language='en', top_line=True, payment_line=True, font_factor=1):
"""
Arguments
Expand All @@ -236,8 +238,8 @@ def __init__(
due_date: str (YYYY-MM-DD)
debtor: Address
Address (combined or structured) of the debtor
extra_infos: str
Extra information aimed for the bill recipient
additional_information: str
Additional information aimed for the bill recipient
alt_procs: list of str (max 2)
two additional fields for alternative payment schemes
language: str
Expand Down Expand Up @@ -320,18 +322,23 @@ def __init__(
else:
self.debtor = debtor

if not ref_number:
if ref_number and reference_number:
raise ValueError("You cannot provide values for both ref_number and reference_number")
if ref_number:
warnings.warn("ref_number is deprecated and replaced by reference_number")
reference_number = ref_number
if not reference_number:
self.ref_type = 'NON'
self.ref_number = None
elif ref_number.strip()[:2].upper() == "RF":
if iso11649.is_valid(ref_number):
self.reference_number = None
elif reference_number.strip()[:2].upper() == "RF":
if iso11649.is_valid(reference_number):
self.ref_type = 'SCOR'
self.ref_number = iso11649.validate(ref_number)
self.reference_number = iso11649.validate(reference_number)
else:
raise ValueError("The reference number is invalid")
elif esr.is_valid(ref_number):
elif esr.is_valid(reference_number):
self.ref_type = 'QRR'
self.ref_number = esr.format(ref_number).replace(" ", "")
self.reference_number = esr.format(reference_number).replace(" ", "")
else:
raise ValueError("The reference number is invalid")

Expand All @@ -344,9 +351,14 @@ def __init__(
if self.ref_type == 'QRR':
raise ValueError("A QRR reference number is only allowed for a QR-IBAN")

if extra_infos and len(extra_infos) > 140:
if extra_infos and additional_information:
raise ValueError("You cannot provide values for both extra_infos and additional_information")
if extra_infos:
warnings.warn("extra_infos is deprecated and replaced by additional_information")
additional_information = extra_infos
if additional_information and len(additional_information) > 140:
raise ValueError("Additional information cannot contain more than 140 characters")
self.extra_infos = extra_infos
self.additional_information = additional_information

if len(alt_procs) > 2:
raise ValueError("Only two lines allowed in alternative procedure parameters")
Expand Down Expand Up @@ -389,7 +401,11 @@ def qr_data(self):
values.extend(self.final_creditor.data_list() if self.final_creditor else [''] * 7)
values.extend([self.amount or '', self.currency or ''])
values.extend(self.debtor.data_list() if self.debtor else [''] * 7)
values.extend([self.ref_type or '', self.ref_number or '', self.extra_infos or ''])
values.extend([
self.ref_type or '',
self.reference_number or '',
self.additional_information or '',
])
values.append('EPD')
values.extend(self.alt_procs)
return "\r\n".join([str(v) for v in values])
Expand Down Expand Up @@ -531,7 +547,7 @@ def draw_bill(self, dwg):
grp.add(dwg.text(line_text, (margin, mm(y_pos)), **self.font_info))
y_pos += line_space

if self.ref_number:
if self.reference_number:
y_pos += 1
grp.add(dwg.text(self.label("Reference"), (margin, mm(y_pos)), **receipt_head_font))
y_pos += line_space
Expand Down Expand Up @@ -666,22 +682,22 @@ def add_header(text, first=False):
grp.add(dwg.text(line_text, (payment_detail_left, mm(y_pos)), **self.font_info))
y_pos += line_space

if self.ref_number:
if self.reference_number:
add_header(self.label("Reference"))
grp.add(dwg.text(
format_ref_number(self), (payment_detail_left, mm(y_pos)), **self.font_info
))
y_pos += line_space

if self.extra_infos:
if self.additional_information:
add_header(self.label("Additional information"))
if '//' in self.extra_infos:
extra_infos = self.extra_infos.split('//')
extra_infos[1] = '//' + extra_infos[1]
if '//' in self.additional_information:
additional_information = self.additional_information.split('//')
additional_information[1] = '//' + additional_information[1]
else:
extra_infos = [self.extra_infos]
additional_information = [self.additional_information]
# TODO: handle line breaks for long infos (mandatory 5mm margin)
for info in wrap_infos(extra_infos):
for info in wrap_infos(additional_information):
grp.add(dwg.text(info, (payment_detail_left, mm(y_pos)), **self.font_info))
y_pos += line_space

Expand Down Expand Up @@ -739,9 +755,9 @@ def mm(val):


def format_ref_number(bill):
if not bill.ref_number:
if not bill.reference_number:
return ''
num = bill.ref_number
num = bill.reference_number
if bill.ref_type == "QRR":
return esr.format(num)
elif bill.ref_type == "SCOR":
Expand Down
7 changes: 4 additions & 3 deletions scripts/qrbill
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ def run():
help='debtor country')
parser.add_argument('--reference-number',
help='reference number')
parser.add_argument('--extra-infos',
# extra-infos kept for backwards compatibility
parser.add_argument('--additional-information', '--extra-infos',
help='payment purpose')
parser.add_argument('--alt-procs',
nargs='*',
Expand Down Expand Up @@ -124,8 +125,8 @@ def run():
currency=args.currency,
due_date=args.due_date,
debtor=debtor,
ref_number=args.reference_number,
extra_infos=args.extra_infos,
reference_number=args.reference_number,
additional_information=args.additional_information,
alt_procs=args.alt_procs,
language=args.language,
top_line=args.top_line,
Expand Down
22 changes: 11 additions & 11 deletions tests/test_qrbill.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,8 @@ def test_spec_example1(self):
'city': 'Rorschach',
'country': 'CH',
},
ref_number='210000000003139471430009017',
extra_infos=(
reference_number='210000000003139471430009017',
additional_information=(
'Order of 15.09.2019//S1/01/20170309/11/10201409/20/1400'
'0000/22/36958/30/CH106017086/40/1020/41/3010'
)
Expand Down Expand Up @@ -359,36 +359,36 @@ def test_reference(self):
self.assertEqual(bill.ref_type, 'NON')
self.assertEqual(format_ref_number(bill), '')

bill = QRBill(**min_data, ref_number='RF18539007547034')
bill = QRBill(**min_data, reference_number='RF18539007547034')
self.assertEqual(bill.ref_type, 'SCOR')
self.assertEqual(format_ref_number(bill), 'RF18 5390 0754 7034')
with self.assertRaisesRegex(ValueError, "The reference number is invalid"):
bill = QRBill(**min_data, ref_number='RF19539007547034')
bill = QRBill(**min_data, reference_number='RF19539007547034')
with self.assertRaisesRegex(ValueError, "A QRR reference number is only allowed for a QR-IBAN"):
bill = QRBill(**min_data, ref_number='18 78583')
bill = QRBill(**min_data, reference_number='18 78583')

min_data = {
'account': "CH 44 3199 9123 0008 89012",
'creditor': {
'name': 'Jane', 'pcode': '1000', 'city': 'Lausanne',
},
}
bill = QRBill(**min_data, ref_number='210000000003139471430009017')
bill = QRBill(**min_data, reference_number='210000000003139471430009017')
self.assertEqual(bill.ref_type, 'QRR')
self.assertEqual(format_ref_number(bill), '21 00000 00003 13947 14300 09017')

# check leading zeros
bill = QRBill(**min_data, ref_number='18 78583')
bill = QRBill(**min_data, reference_number='18 78583')
self.assertEqual(bill.ref_type, 'QRR')
self.assertEqual(format_ref_number(bill), '00 00000 00000 00000 00018 78583')

# invalid QRR
with self.assertRaisesRegex(ValueError, "The reference number is invalid"):
bill = QRBill(**min_data, ref_number='18539007547034')
bill = QRBill(**min_data, reference_number='18539007547034')
with self.assertRaisesRegex(ValueError, "The reference number is invalid"):
bill = QRBill(**min_data, ref_number='ref-number')
bill = QRBill(**min_data, reference_number='ref-number')
with self.assertRaisesRegex(ValueError, "A QR-IBAN requires a QRR reference number"):
bill = QRBill(**min_data, ref_number='RF18539007547034')
bill = QRBill(**min_data, reference_number='RF18539007547034')

def test_alt_procs(self):
min_data = {
Expand Down Expand Up @@ -499,7 +499,7 @@ def test_text_result(self):
sys.executable, 'scripts/qrbill', '--account', 'CH 44 3199 9123 0008 89012',
'--creditor-name', 'Jane', '--creditor-postalcode', '1000',
'--creditor-city', 'Lausanne', '--reference-number', '210000000003139471430009017',
'--extra-infos', 'Order of 15.09.2019', '--text',
'--additional-information', 'Order of 15.09.2019', '--text',
]
out, err = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
Expand Down

0 comments on commit d901682

Please sign in to comment.