Ejemplo n.º 1
0
def test_parse_nonnumeric_value(value: str) -> None:
    with pytest.raises(ParseError) as exc_info:
        Sscc.parse(value)

    assert (
        str(exc_info.value)
        == f"Failed to parse {value!r} as SSCC: Expected a numerical value."
    )
Ejemplo n.º 2
0
def test_parse_with_invalid_check_digit() -> None:
    with pytest.raises(ParseError) as exc_info:
        Sscc.parse("376130321109103421")

    assert (
        str(exc_info.value)
        == "Invalid SSCC check digit for '376130321109103421': Expected 0, got 1."
    )
Ejemplo n.º 3
0
def test_parse_nonnumeric_value() -> None:
    with pytest.raises(ParseError) as exc_info:
        Sscc.parse("012345678901234abc")

    assert (
        str(exc_info.value) ==
        "Failed to parse '012345678901234abc' as SSCC: Expected a numerical value."
    )
Ejemplo n.º 4
0
def test_parse_value_with_invalid_length() -> None:
    with pytest.raises(ParseError) as exc_info:
        Sscc.parse("123")

    assert (
        str(exc_info.value)
        == "Failed to parse '123' as SSCC: Expected 18 digits, got 3."
    )
Ejemplo n.º 5
0
def test_parse() -> None:
    sscc = Sscc.parse("376130321109103420")

    assert sscc == Sscc(
        value="376130321109103420",
        prefix=GS1Prefix(value="761", usage="GS1 Schweiz, Suisse, Svizzera"),
        extension_digit=3,
        payload="37613032110910342",
        check_digit=0,
    )
Ejemplo n.º 6
0
def test_as_hri_with_too_high_company_prefix_length() -> None:
    sscc = Sscc.parse("376130321109103420")

    with pytest.raises(ValueError) as exc_info:
        sscc.as_hri(company_prefix_length=11)

    assert (str(exc_info.value) ==
            "Expected company prefix length between 7 and 10, got 11.")
Ejemplo n.º 7
0
def _parse_sscc(
    value: str,
    *,
    config: ParseConfig,
    queue: ParseQueue,
    result: ParseResult,
) -> None:
    if result.sscc is not None:
        return  # pragma: no cover

    try:
        result.sscc = Sscc.parse(value)
        result.sscc_error = None
    except ParseError as exc:
        result.sscc = None
        result.sscc_error = str(exc)
Ejemplo n.º 8
0
from biip.sscc import Sscc


@pytest.mark.parametrize(
    "value, expected",
    [
        (
            "00373400306809981733",
            GS1ElementString(
                ai=GS1ApplicationIdentifier.extract("00"),
                value="373400306809981733",
                pattern_groups=["373400306809981733"],
                sscc=Sscc(
                    value="373400306809981733",
                    prefix=GS1Prefix(value="734", usage="GS1 Sweden"),
                    extension_digit=3,
                    payload="37340030680998173",
                    check_digit=3,
                ),
            ),
        ),
        (
            "0107032069804988",
            GS1ElementString(
                ai=GS1ApplicationIdentifier.extract("01"),
                value="07032069804988",
                pattern_groups=["07032069804988"],
                gtin=Gtin(
                    value="07032069804988",
                    format=GtinFormat.GTIN_13,
                    prefix=GS1Prefix(value="703", usage="GS1 Norway"),
Ejemplo n.º 9
0
def test_as_hri_with_unknown_gs1_prefix() -> None:
    # GS1 prefix 671 is currently unassigned.
    sscc = Sscc.parse("367130321109103428")

    assert sscc.as_hri() == "3 6713032110910342 8"
Ejemplo n.º 10
0
def test_as_hri(prefix_length: Optional[int], expected: str) -> None:
    sscc = Sscc.parse("376130321109103420")

    assert sscc.as_hri(company_prefix_length=prefix_length) == expected
Ejemplo n.º 11
0
def test_parse_strips_surrounding_whitespace() -> None:
    sscc = Sscc.parse("  \t 376130321109103420 \n  ")

    assert sscc.value == "376130321109103420"
Ejemplo n.º 12
0
def parse(
    value: str,
    *,
    rcn_region: Optional[RcnRegion] = None,
    separator_chars: Iterable[str] = DEFAULT_SEPARATOR_CHARS,
) -> ParseResult:
    """Identify data format and parse data.

    The current strategy is:

    1. If Symbology Identifier prefix indicates a GTIN or GS1 Message,
       attempt to parse and validate as that.
    2. Else, if not Symbology Identifier, attempt to parse with all parsers.

    Args:
        value: The data to classify and parse.
        rcn_region: The geographical region whose rules should be used to
            interpret Restricted Circulation Numbers (RCN).
            Needed to extract e.g. variable weight/price from GTIN.
        separator_chars: Characters used in place of the FNC1 symbol.
            Defaults to `<GS>` (ASCII value 29).
            If variable-length fields in the middle of the message are
            not terminated with a separator character, the parser might
            greedily consume the rest of the message.

    Returns:
        A data class depending upon what type of data is parsed.

    Raises:
        ParseError: If parsing of the data fails.
    """
    value = value.strip()
    result = ParseResult(value=value)

    # Extract Symbology Identifier
    if value.startswith("]"):
        result.symbology_identifier = SymbologyIdentifier.extract(value)
        value = value[len(result.symbology_identifier):]

    # Select parsers
    parsers: List[ParserType] = []
    if result.symbology_identifier is not None:
        if (result.symbology_identifier.gs1_symbology
                in GS1Symbology.with_gtin()):
            parsers.append(Gtin)
        if (result.symbology_identifier.gs1_symbology
                in GS1Symbology.with_ai_element_strings()):
            parsers.append(GS1Message)
    if not parsers:
        # If we're not able to select a subset based on Symbology Identifiers,
        # run all parsers in the default order.
        parsers = [Gtin, Sscc, GS1Message]

    # Run all parsers in order
    for parser in parsers:
        if parser == Gtin:
            try:
                result.gtin = Gtin.parse(value, rcn_region=rcn_region)
            except ParseError as exc:
                result.gtin_error = str(exc)

        if parser == Sscc:
            try:
                result.sscc = Sscc.parse(value)
            except ParseError as exc:
                result.sscc_error = str(exc)

        if parser == GS1Message:
            try:
                result.gs1_message = GS1Message.parse(
                    value,
                    rcn_region=rcn_region,
                    separator_chars=separator_chars,
                )
            except ParseError as exc:
                result.gs1_message_error = str(exc)
            else:
                ai_00 = result.gs1_message.get(ai="00")
                if ai_00 is not None:
                    # GS1 Message contains an SSCC
                    result.sscc = ai_00.sscc
                    # Clear error from parsing full value a SSCC.
                    result.sscc_error = None

                ai_01 = result.gs1_message.get(ai="01")
                if ai_01 is not None:
                    # GS1 Message contains a GTIN.
                    result.gtin = ai_01.gtin
                    # Clear error from parsing full value as GTIN.
                    result.gtin_error = None

    if result._has_result():
        return result
    else:
        raise ParseError(
            f"Failed to parse {value!r}:\n{result._get_errors_list()}")
Ejemplo n.º 13
0
    def _set_sscc(self: GS1ElementString) -> None:
        if self.ai.ai != "00":
            return

        self.sscc = Sscc.parse(self.value)
Ejemplo n.º 14
0
    def _set_sscc(self) -> None:
        if self.ai.ai != "00":
            return

        self.sscc = Sscc.parse(self.value)
Ejemplo n.º 15
0
     ),
 ),
 (
     # SSCC
     "376130321109103420",
     ParseResult(
         value="376130321109103420",
         gs1_message_error=(
             "Failed to get GS1 Application Identifier from '09103420'."
         ),
         gtin_error=("Failed to parse '376130321109103420' as GTIN: "
                     "Expected 8, 12, 13, or 14 digits, got 18."),
         sscc=Sscc(
             value="376130321109103420",
             prefix=GS1Prefix(value="761",
                              usage="GS1 Schweiz, Suisse, Svizzera"),
             extension_digit=3,
             payload="37613032110910342",
             check_digit=0,
         ),
     ),
 ),
 (
     # GS1 AI: SSCC
     "00376130321109103420",
     ParseResult(
         value="00376130321109103420",
         gtin_error=("Failed to parse '00376130321109103420' as GTIN: "
                     "Expected 8, 12, 13, or 14 digits, got 20."),
         gs1_message=GS1Message(
             value="00376130321109103420",
             element_strings=[