{
  "$schema": "../cases.schema.json",
  "format": 1,
  "domain": "serviceItem",
  "title": {
    "en": "Service list (LC 116)",
    "pt-BR": "Lista de serviços (LC 116)"
  },
  "functions": [
    {
      "id": "serviceItem.get",
      "level": "extended",
      "summary": "Looks up a subitem of the LC 116/2003 service list.",
      "description": "Looks up a subitem of the LC 116/2003 service list and returns its code and description.\n\n- Same input rules as `serviceItem.isValid`. Returns `null` exactly when that function returns `false`.\n- The separators of `serviceItem.isValid` are accepted between the item and the subitem (`\"1-01\"` gives code `1.01`).\n- The returned code is the form the law prints: the item without a leading zero, a dot and the 2-digit subitem (`\"1.01\"`, `\"40.01\"`).\n- The description is the text of the national list (ANEXO B of the NFS-e). Subitem 17.14 is \"Advocacia\", with no final period, as in the official sheet.",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        }
      ],
      "returns": "ServiceItem?",
      "cases": [
        {
          "id": "serviceItem.get#[\"1.01\"]",
          "args": [
            "1.01"
          ],
          "expect": {
            "returns": {
              "code": "1.01",
              "description": "Análise e desenvolvimento de sistemas."
            }
          },
          "note": "from the maintainer briefing, #569"
        },
        {
          "id": "serviceItem.get#[\"0101\"]",
          "args": [
            "0101"
          ],
          "expect": {
            "returns": {
              "code": "1.01",
              "description": "Análise e desenvolvimento de sistemas."
            }
          },
          "note": "from the maintainer briefing, #569"
        },
        {
          "id": "serviceItem.get#[\"1.02\"]",
          "args": [
            "1.02"
          ],
          "expect": {
            "returns": {
              "code": "1.02",
              "description": "Programação."
            }
          },
          "note": "JavaScript's own test: should return the subitem for the form the law prints"
        },
        {
          "id": "serviceItem.get#[\"01.01\"]",
          "args": [
            "01.01"
          ],
          "expect": {
            "returns": {
              "code": "1.01",
              "description": "Análise e desenvolvimento de sistemas."
            }
          },
          "note": "JavaScript's own test: should return the subitem for a zero padded item"
        },
        {
          "id": "serviceItem.get#[\"101\"]",
          "args": [
            "101"
          ],
          "expect": {
            "returns": {
              "code": "1.01",
              "description": "Análise e desenvolvimento de sistemas."
            }
          },
          "note": "JavaScript's own test: should return the subitem for the bare digits, the first four of a cTribNac"
        },
        {
          "id": "serviceItem.get#[101]",
          "args": [
            101
          ],
          "expect": {
            "returns": {
              "code": "1.01",
              "description": "Análise e desenvolvimento de sistemas."
            }
          },
          "note": "JavaScript's own test: should return the subitem for the bare digits, the first four of a cTribNac"
        },
        {
          "id": "serviceItem.get#[\"40.01\"]",
          "args": [
            "40.01"
          ],
          "expect": {
            "returns": {
              "code": "40.01",
              "description": "Obras de arte sob encomenda."
            }
          },
          "note": "JavaScript's own test: should return a two digit item without a leading zero in the code"
        },
        {
          "id": "serviceItem.get#[4001]",
          "args": [
            4001
          ],
          "expect": {
            "returns": {
              "code": "40.01",
              "description": "Obras de arte sob encomenda."
            }
          },
          "note": "JavaScript's own test: should return a two digit item without a leading zero in the code"
        },
        {
          "id": "serviceItem.get#[\"10.04\"]",
          "args": [
            "10.04"
          ],
          "expect": {
            "returns": {
              "code": "10.04",
              "description": "Agenciamento, corretagem ou intermediação de contratos de arrendamento mercantil (leasing), de franquia (franchising) e de faturização (factoring)."
            }
          },
          "note": "JavaScript's own test: should return a two digit item without a leading zero in the code"
        },
        {
          "id": "serviceItem.get#[\"11.05\"]",
          "args": [
            "11.05"
          ],
          "expect": {
            "returns": {
              "code": "11.05",
              "description": "Serviços relacionados ao monitoramento e rastreamento a distância, em qualquer via ou local, de veículos, cargas, pessoas e semoventes em circulação ou movimento, realizados por meio de telefonia móvel, transmissão de satélites, rádio ou qualquer outro meio, inclusive pelas empresas de Tecnologia da Informação Veicular, independentemente de o prestador de serviços ser proprietário ou não da infraestrutura de telecomunicações que utiliza."
            }
          },
          "note": "JavaScript's own test: should return the subitem 11.05, added by the Lei Complementar 183/2021"
        },
        {
          "id": "serviceItem.get#[\" 1.01\\n\"]",
          "args": [
            " 1.01\n"
          ],
          "expect": {
            "returns": {
              "code": "1.01",
              "description": "Análise e desenvolvimento de sistemas."
            }
          },
          "note": "JavaScript's own test: should ignore surrounding whitespace"
        },
        {
          "id": "serviceItem.get#[\"17.14\"]",
          "args": [
            "17.14"
          ],
          "expect": {
            "returns": {
              "code": "17.14",
              "description": "Advocacia"
            }
          },
          "note": "JavaScript's own test: should return the subitem 17.14 as the official sheet prints it, without a final period"
        },
        {
          "id": "serviceItem.get#[\"3.01\"]",
          "args": [
            "3.01"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for the vetoed subitems"
        },
        {
          "id": "serviceItem.get#[\"7.14\"]",
          "args": [
            "7.14"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for the vetoed subitems"
        },
        {
          "id": "serviceItem.get#[\"7.15\"]",
          "args": [
            "7.15"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for the vetoed subitems"
        },
        {
          "id": "serviceItem.get#[\"13.01\"]",
          "args": [
            "13.01"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for the vetoed subitems"
        },
        {
          "id": "serviceItem.get#[\"17.07\"]",
          "args": [
            "17.07"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for the vetoed subitems"
        },
        {
          "id": "serviceItem.get#[\"99.01\"]",
          "args": [
            "99.01"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for item 99 of the national list, which is not part of the law"
        },
        {
          "id": "serviceItem.get#[\"1\"]",
          "args": [
            "1"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for an item heading and for a 6 digit national code"
        },
        {
          "id": "serviceItem.get#[\"010101\"]",
          "args": [
            "010101"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for an item heading and for a 6 digit national code"
        },
        {
          "id": "serviceItem.get#[\"1.01.01\"]",
          "args": [
            "1.01.01"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for an item heading and for a 6 digit national code"
        },
        {
          "id": "serviceItem.get#[\"1.10\"]",
          "args": [
            "1.10"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a subitem the list does not carry"
        },
        {
          "id": "serviceItem.get#[\"41.01\"]",
          "args": [
            "41.01"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a subitem the list does not carry"
        },
        {
          "id": "serviceItem.get#[\"1.1\"]",
          "args": [
            "1.1"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a string that is not written in a documented form"
        },
        {
          "id": "serviceItem.get#[\"1-01\"]",
          "args": [
            "1-01"
          ],
          "expect": {
            "returns": {
              "code": "1.01",
              "description": "Análise e desenvolvimento de sistemas."
            }
          },
          "note": "any run of separators is accepted between the item and the subitem; the code returned is the form the law prints"
        },
        {
          "id": "serviceItem.get#[\"1,01\"]",
          "args": [
            "1,01"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a string that is not written in a documented form"
        },
        {
          "id": "serviceItem.get#[\"001.01\"]",
          "args": [
            "001.01"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a string that is not written in a documented form"
        },
        {
          "id": "serviceItem.get#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for an empty string and for whitespace only"
        },
        {
          "id": "serviceItem.get#[1.01]",
          "args": [
            1.01
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a number that is not a non-negative safe integer"
        },
        {
          "id": "serviceItem.get#[-101]",
          "args": [
            -101
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a number that is not a non-negative safe integer"
        },
        {
          "id": "serviceItem.get#[\"1 01\"]",
          "args": [
            "1 01"
          ],
          "expect": {
            "returns": {
              "code": "1.01",
              "description": "Análise e desenvolvimento de sistemas."
            }
          },
          "note": "a run of separators is accepted, as in serviceItem.isValid"
        },
        {
          "id": "serviceItem.get#[\"1..01\"]",
          "args": [
            "1..01"
          ],
          "expect": {
            "returns": {
              "code": "1.01",
              "description": "Análise e desenvolvimento de sistemas."
            }
          },
          "note": "a run of separators is accepted, as in serviceItem.isValid"
        },
        {
          "id": "serviceItem.get#[\"1_01\"]",
          "args": [
            "1_01"
          ],
          "expect": {
            "returns": null
          },
          "note": "an underscore is not a mask separator"
        }
      ]
    },
    {
      "id": "serviceItem.isValid",
      "level": "extended",
      "summary": "Checks whether a value is a subitem in force of the LC 116/2003 service list.",
      "description": "Checks whether a value is a subitem in force of the service list annexed to Lei Complementar 116/2003.\n\n- Accepts the form the law prints (`\"1.01\"`), a zero-padded item (`\"01.01\"`), the bare digits (`\"0101\"`, `\"101\"`, the first 4 digits of a cTribNac) or a non-negative integer (`101`). Whitespace around the value is ignored.\n- The subitem always has 2 digits (`\"1.1\"` is invalid). Any run of separators (space, `.`, `-` or `/`) is accepted between the item and the subitem, so `\"1-01\"`, `\"1 01\"` and `\"1..01\"` are valid; any other character (`\"1_01\"`, `\"1,01\"`) is rejected. A number is read as bare digits, so the fractional number `1.01` is invalid: write the dotted form as a string.\n- The vetoed subitems 3.01, 7.14, 7.15, 13.01 and 17.07 are invalid. So are item headings (`\"1\"`), the 6-digit national codes and item 99 of the national list, which is not part of the law.\n- Subitem 11.05, added by LC 183/2021, is valid.\n- cTribNac and cTribMun are out of scope.",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        }
      ],
      "returns": "boolean",
      "cases": [
        {
          "id": "serviceItem.isValid#[\"3.01\"]",
          "args": [
            "3.01"
          ],
          "expect": {
            "returns": false
          },
          "note": "from the maintainer briefing, #569"
        },
        {
          "id": "serviceItem.isValid#[\"99.01\"]",
          "args": [
            "99.01"
          ],
          "expect": {
            "returns": false
          },
          "note": "from the maintainer briefing, #569"
        },
        {
          "id": "serviceItem.isValid#[\"1.01\"]",
          "args": [
            "1.01"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate a subitem in the form the law prints"
        },
        {
          "id": "serviceItem.isValid#[\"17.25\"]",
          "args": [
            "17.25"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate a subitem in the form the law prints"
        },
        {
          "id": "serviceItem.isValid#[\"40.01\"]",
          "args": [
            "40.01"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate a subitem in the form the law prints"
        },
        {
          "id": "serviceItem.isValid#[\"01.01\"]",
          "args": [
            "01.01"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate a zero padded item and the bare digits"
        },
        {
          "id": "serviceItem.isValid#[\"0101\"]",
          "args": [
            "0101"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate a zero padded item and the bare digits"
        },
        {
          "id": "serviceItem.isValid#[101]",
          "args": [
            101
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate a zero padded item and the bare digits"
        },
        {
          "id": "serviceItem.isValid#[\"101\"]",
          "args": [
            "101"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate the bare digits of an item with one digit"
        },
        {
          "id": "serviceItem.isValid#[\"17.07\"]",
          "args": [
            "17.07"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject the vetoed subitems"
        },
        {
          "id": "serviceItem.isValid#[\"010101\"]",
          "args": [
            "010101"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject item 99 of the national list and the 6 digit national codes"
        },
        {
          "id": "serviceItem.isValid#[\"1.1\"]",
          "args": [
            "1.1"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject a malformed value"
        },
        {
          "id": "serviceItem.isValid#[\"1-01\"]",
          "args": [
            "1-01"
          ],
          "expect": {
            "returns": true
          },
          "note": "any run of separators is accepted between the item and the subitem. JavaScript's own test: should accept the mask characters isValidCpf reads at the one boundary, alone or in a run"
        },
        {
          "id": "serviceItem.isValid#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject a malformed value"
        },
        {
          "id": "serviceItem.isValid#[1.01]",
          "args": [
            1.01
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject null, undefined and non lookup values"
        },
        {
          "id": "serviceItem.isValid#[\"  1.01\\n\"]",
          "args": [
            "  1.01\n"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should ignore surrounding whitespace"
        },
        {
          "id": "serviceItem.isValid#[\"constructor\"]",
          "args": [
            "constructor"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject the keys of Object.prototype"
        },
        {
          "id": "serviceItem.isValid#lc-183-2021",
          "args": [
            "11.05"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "serviceItem.isValid#vetoed-7-14",
          "args": [
            "7.14"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "serviceItem.isValid#vetoed-7-15",
          "args": [
            "7.15"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "serviceItem.isValid#vetoed-13-01",
          "args": [
            "13.01"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "serviceItem.isValid#negative",
          "args": [
            -101
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "serviceItem.isValid#[\"1 01\"]",
          "args": [
            "1 01"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the mask characters isValidCpf reads at the one boundary, alone or in a run"
        },
        {
          "id": "serviceItem.isValid#[\"1..01\"]",
          "args": [
            "1..01"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the mask characters isValidCpf reads at the one boundary, alone or in a run"
        },
        {
          "id": "serviceItem.isValid#[\"1/01\"]",
          "args": [
            "1/01"
          ],
          "expect": {
            "returns": true
          },
          "note": "the slash is one of the mask separators"
        },
        {
          "id": "serviceItem.isValid#[\"1_01\"]",
          "args": [
            "1_01"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should reject a malformed value"
        },
        {
          "id": "serviceItem.isValid#[\"1,01\"]",
          "args": [
            "1,01"
          ],
          "expect": {
            "returns": false
          },
          "note": "a comma is not a mask separator"
        },
        {
          "id": "serviceItem.isValid#[\"1.01.01\"]",
          "args": [
            "1.01.01"
          ],
          "expect": {
            "returns": false
          },
          "note": "an item heading plus a 6-digit national code is not a subitem"
        }
      ]
    }
  ]
}
