{
  "$schema": "../cases.schema.json",
  "format": 1,
  "domain": "cfop",
  "title": {
    "en": "CFOP",
    "pt-BR": "CFOP"
  },
  "functions": [
    {
      "id": "cfop.format",
      "level": "extended",
      "summary": "Formats a CFOP code with the mask `N.NNN`.",
      "description": "Formats a CFOP code with the mask `N.NNN`. Only the structure changes (use `cfop.isValid` to check the code against the table).\n\n- The mask is applied as far as the digits go, so a value being typed is masked progressively.\n- `options.pad` (default `false`) first left-pads the value with zeros to 4 digits. A number is treated as the string of its digits, so it is padded only with `pad`.\n- A string is read for its digits: other characters are dropped and digits after the last one of the mask are ignored.\n- An empty value, or one without digits, returns an empty string even with `pad`. `null` and `undefined` return an empty string too.\n- A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number returns an empty string.\n- No CFOP starts with a zero, so `pad` only serves a caller that wants a fixed width.\n- New in 2.5.0 (#615), so every masked classification code has its formatter.",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        },
        {
          "name": "options",
          "type": "FormatCfopOptions",
          "optional": true
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "cfop.format#[\"5102\"]",
          "args": [
            "5102"
          ],
          "expect": {
            "returns": "5.102"
          },
          "note": "JavaScript's own test: should format a CFOP code given as digits"
        },
        {
          "id": "cfop.format#[5102]",
          "args": [
            5102
          ],
          "expect": {
            "returns": "5.102"
          },
          "note": "JavaScript's own test: should format a CFOP code given as a number"
        },
        {
          "id": "cfop.format#[\"5.102\"]",
          "args": [
            "5.102"
          ],
          "expect": {
            "returns": "5.102"
          },
          "note": "JavaScript's own test: should format a CFOP code that already has the mask"
        },
        {
          "id": "cfop.format#[\"51\"]",
          "args": [
            "51"
          ],
          "expect": {
            "returns": "5.1"
          },
          "note": "JavaScript docs example"
        },
        {
          "id": "cfop.format#[\"5\"]",
          "args": [
            "5"
          ],
          "expect": {
            "returns": "5"
          },
          "note": "JavaScript's own test: should mask a partial value progressively by default"
        },
        {
          "id": "cfop.format#[\"\"]",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string for an empty value"
        },
        {
          "id": "cfop.format#[\"\",{\"pad\":true}]",
          "args": [
            "",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: pad option should left pad a short code with zeros up to the full CFOP length"
        },
        {
          "id": "cfop.format#[\"2\",{\"pad\":true}]",
          "args": [
            "2",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0.002"
          },
          "note": "JavaScript's own test: pad option should left pad a short code with zeros up to the full CFOP length"
        },
        {
          "id": "cfop.format#[\"102\",{\"pad\":true}]",
          "args": [
            "102",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0.102"
          },
          "note": "JavaScript's own test: pad option should left pad a short code with zeros up to the full CFOP length"
        },
        {
          "id": "cfop.format#[\"5102\",{\"pad\":true}]",
          "args": [
            "5102",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "5.102"
          },
          "note": "JavaScript's own test: pad option should left pad a short code with zeros up to the full CFOP length"
        },
        {
          "id": "cfop.format#[102,{\"pad\":true}]",
          "args": [
            102,
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0.102"
          },
          "note": "JavaScript's own test: pad option should left pad a number the same way as its digits"
        },
        {
          "id": "cfop.format#[null]",
          "args": [
            null
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string for null and undefined, even under pad"
        },
        {
          "id": "cfop.format#[null,{\"pad\":true}]",
          "args": [
            null,
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string for null and undefined, even under pad"
        },
        {
          "id": "cfop.format#[\"abc5102\"]",
          "args": [
            "abc5102"
          ],
          "expect": {
            "returns": "5.102"
          },
          "note": "JavaScript docs example"
        },
        {
          "id": "cfop.format#[\"5102999\"]",
          "args": [
            "5102999"
          ],
          "expect": {
            "returns": "5.102"
          }
        },
        {
          "id": "cfop.format#[-5102]",
          "args": [
            -5102
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript docs example"
        },
        {
          "id": "cfop.format#[5102.5]",
          "args": [
            5102.5
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: when it is a negative, fractional or unsafe number"
        },
        {
          "id": "cfop.format#[9007199254740992]",
          "args": [
            9007199254740992
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: when it is a negative, fractional or unsafe number"
        },
        {
          "id": "cfop.format#[-5102,{\"pad\":true}]",
          "args": [
            -5102,
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: when it is a negative, fractional or unsafe number"
        }
      ]
    },
    {
      "id": "cfop.get",
      "level": "extended",
      "summary": "Looks up a CFOP code in the official table.",
      "description": "Looks up a CFOP code in the official table and returns its code and description.\n\n- Same input rules as `cfop.isValid`, including a run of separators between the groups (`5..102` gives the entry; until 2.4.0 it gave `null`). Returns `null` for a heading, an unknown code or a value not in an accepted form.\n- It returns `null` exactly when `cfop.isValid` returns `false`.",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        }
      ],
      "returns": "Cfop?",
      "cases": [
        {
          "id": "cfop.get#[\"5102\"]",
          "args": [
            "5102"
          ],
          "expect": {
            "returns": {
              "code": "5102",
              "description": "Venda de mercadoria adquirida ou recebida de terceiros, ou qualquer venda de mercadoria efetuada pelo MEI com exceção das saídas classificadas nos códigos 5.501, 5.502, 5.504 e 5.505"
            }
          }
        },
        {
          "id": "cfop.get#masked",
          "args": [
            "5.102"
          ],
          "expect": {
            "returns": {
              "code": "5102",
              "description": "Venda de mercadoria adquirida ou recebida de terceiros, ou qualquer venda de mercadoria efetuada pelo MEI com exceção das saídas classificadas nos códigos 5.501, 5.502, 5.504 e 5.505"
            }
          }
        },
        {
          "id": "cfop.get#group-heading",
          "args": [
            "1100"
          ],
          "expect": {
            "returns": null
          }
        },
        {
          "id": "cfop.get#too-short",
          "args": [
            "510"
          ],
          "expect": {
            "returns": null
          }
        },
        {
          "id": "cfop.get#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": null
          }
        },
        {
          "id": "cfop.get#[5102]",
          "args": [
            5102
          ],
          "expect": {
            "returns": {
              "code": "5102",
              "description": "Venda de mercadoria adquirida ou recebida de terceiros, ou qualquer venda de mercadoria efetuada pelo MEI com exceção das saídas classificadas nos códigos 5.501, 5.502, 5.504 e 5.505"
            }
          },
          "note": "JavaScript's own test: should return the CFOP entry for a known code as a number"
        },
        {
          "id": "cfop.get#[\"1255\"]",
          "args": [
            "1255"
          ],
          "expect": {
            "returns": {
              "code": "1255",
              "description": "Compra de energia elétrica por estabelecimento prestador de serviço de comunicação"
            }
          },
          "note": "JavaScript's own test: should return one entry per code even when the annex glues the body into the code line (1255 and 1256)"
        },
        {
          "id": "cfop.get#[\"1256\"]",
          "args": [
            "1256"
          ],
          "expect": {
            "returns": {
              "code": "1256",
              "description": "Compra de energia elétrica por estabelecimento de produtor rural"
            }
          },
          "note": "JavaScript's own test: should return one entry per code even when the annex glues the body into the code line (1255 and 1256)"
        },
        {
          "id": "cfop.get#[\"7504\"]",
          "args": [
            "7504"
          ],
          "expect": {
            "returns": {
              "code": "7504",
              "description": "Exportação de mercadoria que foi objeto de formação de lote de exportação"
            }
          },
          "note": "JavaScript's own test: should resolve the codes the 2022 and 2024 rewrites of the annex added (7504, 6360, 2128 and 1934)"
        },
        {
          "id": "cfop.get#[\"6360\"]",
          "args": [
            "6360"
          ],
          "expect": {
            "returns": {
              "code": "6360",
              "description": "Prestação de serviço de transporte a contribuinte substituto em relação ao serviço de transporte"
            }
          },
          "note": "JavaScript's own test: should resolve the codes the 2022 and 2024 rewrites of the annex added (7504, 6360, 2128 and 1934)"
        },
        {
          "id": "cfop.get#[\"2128\"]",
          "args": [
            "2128"
          ],
          "expect": {
            "returns": {
              "code": "2128",
              "description": "Compra para utilização na prestação de serviço sujeita ao ISSQN"
            }
          },
          "note": "JavaScript's own test: should resolve the codes the 2022 and 2024 rewrites of the annex added (7504, 6360, 2128 and 1934)"
        },
        {
          "id": "cfop.get#[\"1934\"]",
          "args": [
            "1934"
          ],
          "expect": {
            "returns": {
              "code": "1934",
              "description": "Entrada simbólica de mercadoria recebida para depósito em depósito fechado ou armazém geral"
            }
          },
          "note": "JavaScript's own test: should resolve the codes the 2022 and 2024 rewrites of the annex added (7504, 6360, 2128 and 1934)"
        },
        {
          "id": "cfop.get#[\"0000\"]",
          "args": [
            "0000"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for an unknown 4 digit code"
        },
        {
          "id": "cfop.get#[\"5300\"]",
          "args": [
            "5300"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a group heading (a code ending in 00)"
        },
        {
          "id": "cfop.get#[\"1150\"]",
          "args": [
            "1150"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a subgroup heading (a code ending in 50)"
        },
        {
          "id": "cfop.get#[\"5350\"]",
          "args": [
            "5350"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a subgroup heading (a code ending in 50)"
        },
        {
          "id": "cfop.get#[\"1151\"]",
          "args": [
            "1151"
          ],
          "expect": {
            "returns": {
              "code": "1151",
              "description": "Transferência para industrialização ou produção rural"
            }
          },
          "note": "JavaScript's own test: should still resolve the operable codes a subgroup heading heads (1151 and 5351)"
        },
        {
          "id": "cfop.get#[\"5351\"]",
          "args": [
            "5351"
          ],
          "expect": {
            "returns": {
              "code": "5351",
              "description": "Prestação de serviço de transporte para execução de serviço da mesma natureza"
            }
          },
          "note": "JavaScript's own test: should still resolve the operable codes a subgroup heading heads (1151 and 5351)"
        },
        {
          "id": "cfop.get#[\"abc5102\"]",
          "args": [
            "abc5102"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a string that is not a documented form"
        },
        {
          "id": "cfop.get#[\"5..102\"]",
          "args": [
            "5..102"
          ],
          "expect": {
            "returns": {
              "code": "5102",
              "description": "Venda de mercadoria adquirida ou recebida de terceiros, ou qualquer venda de mercadoria efetuada pelo MEI com exceção das saídas classificadas nos códigos 5.501, 5.502, 5.504 e 5.505"
            }
          },
          "note": "changed in 2.5.0 (#615): a run of separators between the groups is accepted (2.4.0 gave null). JavaScript's own test: should accept a group boundary written with a run of separators"
        },
        {
          "id": "cfop.get#[-5102]",
          "args": [
            -5102
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a number that is not a non-negative safe integer"
        },
        {
          "id": "cfop.get#[51.02]",
          "args": [
            51.02
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for a number that is not a non-negative safe integer"
        }
      ]
    },
    {
      "id": "cfop.isValid",
      "level": "extended",
      "summary": "Checks whether a CFOP code exists in the official table.",
      "description": "Checks whether a CFOP code exists in the consolidated Anexo II of Convênio SINIEF s/nº 1970 in force.\n\n- Only operable codes count: the function rejects group and subgroup headings (codes ending in `00` and `50`).\n- Accepts the 4 digits, the `N.NNN` form or a safe non-negative integer. A masked string may have any run of separators (space, `.`, `-` or `/`) between the groups: `5..102` is valid. Until 2.4.0 the form had a single separator and `5..102` was rejected. Any other string is rejected.\n- Whitespace around the value is ignored.\n- No CFOP starts with a zero, so the function pads nothing.",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        }
      ],
      "returns": "boolean",
      "cases": [
        {
          "id": "cfop.isValid#[\"5102\"]",
          "args": [
            "5102"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "cfop.isValid#masked",
          "args": [
            "5.102"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "cfop.isValid#[\"7504\"]",
          "args": [
            "7504"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "cfop.isValid#[\"0000\"]",
          "args": [
            "0000"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "cfop.isValid#group-heading",
          "args": [
            "1100"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "cfop.isValid#too-short",
          "args": [
            "510"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "cfop.isValid#letters",
          "args": [
            "abcd"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "cfop.isValid#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "cfop.isValid#[5102]",
          "args": [
            5102
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for a known CFOP code as a number"
        },
        {
          "id": "cfop.isValid#[\" 5102 \"]",
          "args": [
            " 5102 "
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for a code with surrounding whitespace"
        },
        {
          "id": "cfop.isValid#[\"6360\"]",
          "args": [
            "6360"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the codes the 2022 and 2024 rewrites of the annex added (7504, 6360, 2128 and 1934)"
        },
        {
          "id": "cfop.isValid#[\"2128\"]",
          "args": [
            "2128"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the codes the 2022 and 2024 rewrites of the annex added (7504, 6360, 2128 and 1934)"
        },
        {
          "id": "cfop.isValid#[\"1934\"]",
          "args": [
            "1934"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the codes the 2022 and 2024 rewrites of the annex added (7504, 6360, 2128 and 1934)"
        },
        {
          "id": "cfop.isValid#[\"1131\"]",
          "args": [
            "1131"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the ato cooperativo and Sistema de Integração e Parceria Rural series (1131 and 1453)"
        },
        {
          "id": "cfop.isValid#[\"1453\"]",
          "args": [
            "1453"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept the ato cooperativo and Sistema de Integração e Parceria Rural series (1131 and 1453)"
        },
        {
          "id": "cfop.isValid#[\"1255\"]",
          "args": [
            "1255"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should accept a code whose body the annex glues into the code line (1255)"
        },
        {
          "id": "cfop.isValid#[\"5300\"]",
          "args": [
            "5300"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a group heading (a code ending in 00)"
        },
        {
          "id": "cfop.isValid#[\"1150\"]",
          "args": [
            "1150"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a subgroup heading (a code ending in 50)"
        },
        {
          "id": "cfop.isValid#[\"5350\"]",
          "args": [
            "5350"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a subgroup heading (a code ending in 50)"
        },
        {
          "id": "cfop.isValid#[\"1151\"]",
          "args": [
            "1151"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should still accept the operable codes a subgroup heading heads (1151 and 5351)"
        },
        {
          "id": "cfop.isValid#[\"5351\"]",
          "args": [
            "5351"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should still accept the operable codes a subgroup heading heads (1151 and 5351)"
        },
        {
          "id": "cfop.isValid#[\"51020\"]",
          "args": [
            "51020"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a code with a length different from 4"
        },
        {
          "id": "cfop.isValid#[\"abc5102\"]",
          "args": [
            "abc5102"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a string that is not a documented form"
        },
        {
          "id": "cfop.isValid#[\"5..102\"]",
          "args": [
            "5..102"
          ],
          "expect": {
            "returns": true
          },
          "note": "changed in 2.5.0 (#615): a run of separators between the groups is accepted (2.4.0 rejected it). JavaScript's own test: should accept a group boundary written with a run of separators"
        },
        {
          "id": "cfop.isValid#[-5102]",
          "args": [
            -5102
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a number that is not a non-negative safe integer"
        },
        {
          "id": "cfop.isValid#[51.02]",
          "args": [
            51.02
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a number that is not a non-negative safe integer"
        }
      ]
    },
    {
      "id": "cfop.parse",
      "level": "extended",
      "summary": "Removes the formatting characters of a CFOP code and returns only the digits.",
      "description": "Removes CFOP formatting and keeps only digits, capped at 4 digits.\n\n- The function does not pad the result.\n- Returns an empty string when there is no digit at all (`null` and `undefined` included).\n- A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number returns an empty string (2.4.0 read the digits of any number, sign and decimal point dropped).",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "cfop.parse#masked",
          "args": [
            "5.102"
          ],
          "expect": {
            "returns": "5102"
          }
        },
        {
          "id": "cfop.parse#unmasked",
          "args": [
            "5102"
          ],
          "expect": {
            "returns": "5102"
          }
        },
        {
          "id": "cfop.parse#strips-non-digits",
          "args": [
            "5?ABC.102abc"
          ],
          "expect": {
            "returns": "5102"
          }
        },
        {
          "id": "cfop.parse#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          }
        },
        {
          "id": "cfop.parse#caps-length",
          "args": [
            "5102999"
          ],
          "expect": {
            "returns": "5102"
          },
          "note": "reference truncates to the 4 characters of the document; asserted by the reference (JS) unit tests"
        },
        {
          "id": "cfop.parse#[5102]",
          "args": [
            5102
          ],
          "expect": {
            "returns": "5102"
          },
          "note": "JavaScript's own test: should read a number as the string of its digits"
        },
        {
          "id": "cfop.parse#[51.02]",
          "args": [
            51.02
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is a negative, fractional or unsafe number (#593 number rule)"
        },
        {
          "id": "cfop.parse#[-1]",
          "args": [
            -1
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is a negative, fractional or unsafe number (#593 number rule)"
        },
        {
          "id": "cfop.parse#[9007199254740992]",
          "args": [
            9007199254740992
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is a negative, fractional or unsafe number (#593 number rule)"
        }
      ]
    }
  ]
}
