Functional Weave
Code in Python

logistics.sscc@1.1.0

impl/python.py

1,694 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

import re

from .validation_gs1_check_digit import gs1_check_digit  ← from validation.gs1-check-digit ^1.0.0 · built alongside by fune

_PREFIX = re.compile(r"^[0-9]{4,12}$")


def _whole(value: object) -> bool:
    return isinstance(value, int) and not isinstance(value, bool)


def build_sscc(extension_digit: int, company_prefix: str, serial_reference: int) -> str:
    """Build an 18-digit SSCC: extension digit, GS1 company prefix, zero-padded
    serial reference and GS1 mod-10 check digit."""
    if not _whole(extension_digit) or extension_digit < 0 or extension_digit > 9:
        raise ValueError("extensionDigit must be 0 to 9, received %r" % (extension_digit,))
    # fullmatch, not match: "$" in re also matches before a trailing newline.
    if not isinstance(company_prefix, str) or not _PREFIX.fullmatch(company_prefix):
        raise ValueError('companyPrefix must be 4 to 12 digits, received "%s"' % (company_prefix,))
    if not _whole(serial_reference):
        raise TypeError("serialReference must be an integer, received %r" % (serial_reference,))
    if serial_reference < 0:
        raise ValueError("serialReference must not be negative, received %d" % serial_reference)
    # Prefix and serial share 16 digits, so a longer prefix leaves less room.
    # Too large is an error: truncating would reuse another unit's number.
    room = 16 - len(company_prefix)
    serial = str(serial_reference)
    if len(serial) > room:
        raise ValueError(
            "serialReference must fit in %d digits after a %d-digit company prefix, received %d"
            % (room, len(company_prefix), serial_reference)
        )
    data = str(extension_digit) + company_prefix + serial.rjust(room, "0")
    return data + str(gs1_check_digit(data))