0002-template-filter-for-Luhn-algorithm-35013.patch
tests/test_templates.py | ||
---|---|---|
534 | 534 |
assert tmpl.render() == '' |
535 | 535 |
tmpl = Template('{{ " 1 23 4 "|clean_number }}') |
536 | 536 |
assert tmpl.render() == '1234' |
537 | ||
538 | ||
539 |
def test_luhn(): |
|
540 |
# Failing cases |
|
541 |
tmpl = Template('{% if None|is_valid_siret%}yes{% endif %}') |
|
542 |
assert tmpl.render() == '' |
|
543 |
tmpl = Template('{% if True|is_valid_siret%}yes{% endif %}') |
|
544 |
assert tmpl.render() == '' |
|
545 |
tmpl = Template('{% if False|is_valid_siret%}yes{% endif %}') |
|
546 |
assert tmpl.render() == '' |
|
547 | ||
548 |
# EO Siret |
|
549 |
tmpl = Template('{% if "44317013900036"|is_valid_siret%}yes{% endif %}') |
|
550 |
assert tmpl.render() == 'yes' |
|
551 |
tmpl = Template('{% if 44317013900036|is_valid_siret%}yes{% endif %}') |
|
552 |
assert tmpl.render() == 'yes' |
|
553 | ||
554 |
# with spaces |
|
555 |
tmpl = Template('{% if " 443 170\t139 00 036 "|clean_number|is_valid_siret %}yes{% endif %}') |
|
556 |
assert tmpl.render() == 'yes' |
|
557 |
for i in range(10): |
|
558 |
if i == 6: |
|
559 |
continue |
|
560 |
tmpl = Template('{% if "4431701390003' + str(i) + '"|is_valid_siret %}yes{% endif %}') |
|
561 |
assert tmpl.render() == '' |
|
562 | ||
563 |
# EO Siren |
|
564 |
tmpl = Template('{% if "443170139"|is_valid_siren %}yes{% endif %}') |
|
565 |
assert tmpl.render() == 'yes' |
|
566 |
for i in range(10): |
|
567 |
if i == 9: |
|
568 |
continue |
|
569 |
tmpl = Template('{% if "44317013' + str(i) + '"|is_valid_siren %}yes{% endif %}') |
|
570 |
assert tmpl.render() == '' |
|
571 | ||
572 |
# credit card number |
|
573 |
tmpl = Template('{% if "5555 5555 5555 4444"|clean_number|is_valid_credit_card_number %}yes{% endif %}') |
|
574 |
assert tmpl.render() == 'yes' |
|
575 | ||
576 |
# La poste |
|
577 |
tmpl = Template('{% if "356 000 000"|clean_number|is_valid_siren%}yes{% endif %}') |
|
578 |
assert tmpl.render() == 'yes' |
|
579 | ||
580 |
tmpl = Template('{% if "356 000 000 12345"|clean_number|is_valid_siret%}yes{% endif %}') |
|
581 |
assert tmpl.render() == 'yes' |
wcs/qommon/templatetags/qommon.py | ||
---|---|---|
359 | 359 |
if not string_value.isdigit(): |
360 | 360 |
return u'' |
361 | 361 |
return string_value |
362 | ||
363 |
def is_valid_luhn(value, length=None): |
|
364 |
'''Verify Luhn checksum on a string representing a number''' |
|
365 |
if not value: |
|
366 |
return False |
|
367 |
string_value = unicode(value) |
|
368 |
if length is not None and len(string_value) != length: |
|
369 |
return False |
|
370 | ||
371 |
# take all digits couting from the right, double value for digits pair |
|
372 |
# index (counting from 1), if double has 2 digits take their sum |
|
373 |
checksum = 0 |
|
374 |
for i, x in enumerate(reversed(string_value)): |
|
375 |
if i % 2 == 0: |
|
376 |
checksum += int(x) |
|
377 |
else: |
|
378 |
checksum += sum(int(y) for y in str(2 * int(x))) |
|
379 |
return checksum % 10 == 0 |
|
380 | ||
381 |
@register.filter |
|
382 |
def is_valid_siren(value): |
|
383 |
if not value: |
|
384 |
return False |
|
385 |
string_value = unicode(value) |
|
386 |
# special case : La Poste |
|
387 |
la_poste = string_value == '356000000' |
|
388 |
return is_valid_luhn(string_value, length=9) or la_poste |
|
389 | ||
390 |
@register.filter |
|
391 |
def is_valid_siret(value): |
|
392 |
if not value: |
|
393 |
return False |
|
394 |
string_value = unicode(value) |
|
395 |
# special case : La Poste |
|
396 |
la_poste = unicode(string_value).startswith('356000000') and len(unicode(string_value)) == 14 |
|
397 |
return is_valid_luhn(string_value, length=14) or la_poste |
|
398 | ||
399 |
@register.filter |
|
400 |
def is_valid_credit_card_number(value): |
|
401 |
return is_valid_luhn(value, length=16) |
|
362 |
- |