diff options
Diffstat (limited to 'src/cepis-lookup.cob')
| -rw-r--r-- | src/cepis-lookup.cob | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/cepis-lookup.cob b/src/cepis-lookup.cob index cc6e412..90f1502 100644 --- a/src/cepis-lookup.cob +++ b/src/cepis-lookup.cob @@ -22,6 +22,13 @@ PROGRAM-ID. CEPIS-LOOKUP. *> means the CEP is a whole municipality and the point is its centroid, *> with a radius of 7 to 40 km. Computing shipping from the second is *> wrong by tens of kilometres. +*> +*> A CEPIS-NOT-FOUND may come back with CEPIS-FAIXA filled: the +*> municipality the CEP would have belonged to. A CEP that fails is +*> rarely a random number -- it is usually someone who knows the city and +*> guessed the digits, and the classic guess is the -000 that 957 +*> municipalities never received. The lookup has still failed and the +*> address is still empty; CEPIS-FAIXA only names where the guess landed. *> --------------------------------------------------------------------- DATA DIVISION. @@ -38,6 +45,17 @@ COPY "cepis-json.cpy". 01 WS-LON PIC S9(3)V9(6). 01 WS-RAIO PIC 9(9). 01 WS-PRECISAO PIC X(16). +01 WS-FAIXA-FROM PIC 9(9). +01 WS-FAIXA-TO PIC 9(9). +01 WS-FAIXA-OK PIC X. +01 WS-F-LOCALIDADE PIC X(100). +01 WS-F-UF PIC X(2). +01 WS-F-ESTADO PIC X(60). +01 WS-F-REGIAO PIC X(30). +01 WS-F-IBGE PIC X(10). +01 WS-F-CEP-INI PIC X(8). +01 WS-F-CEP-FIM PIC X(8). +01 WS-F-CEPS PIC 9(9). 01 WS-I PIC 9(4). 01 WS-C PIC X. 01 WS-DOTS PIC 9(4). @@ -82,6 +100,7 @@ MAIN-START. STRING "CEP " WS-CEP " does not exist in the DNE database" DELIMITED BY SIZE INTO CEPIS-STATUS-MESSAGE END-STRING + PERFORM PARSE-FAIXA WHEN 400 SET CEPIS-INVALID-CEP TO TRUE PERFORM API-MESSAGE @@ -133,6 +152,13 @@ GET-GEO-MEMBER. END-CALL. *> ------------------------------------------------------------------- +GET-FAIXA-MEMBER. + MOVE WS-FAIXA-FROM TO JS-FROM + MOVE WS-FAIXA-TO TO JS-TO + CALL "CEPIS-JSON-GET" USING HTTP-BODY CEPIS-JSON-SCAN + END-CALL. + +*> ------------------------------------------------------------------- PARSE-ADDRESS. MOVE "cep" TO JS-KEY PERFORM GET-MEMBER @@ -290,6 +316,115 @@ PARSE-GEO. END-IF. *> ------------------------------------------------------------------- +*> The 404 body may name the municipality the CEP would have belonged +*> to. It is context for the error and nothing else: the status stays +*> CEPIS-NOT-FOUND and CEPIS-ADDRESS stays empty, because a CEP that the +*> DNE does not have is not an address no matter which city it is near. +*> +*> "faixa" is omitted -- never sent as null -- when the CEP falls in a +*> band no municipality owns, so its absence is the normal case, not an +*> error. Everything here is therefore best effort: a faixa that is +*> missing, is not an object, or is short of the members below is +*> dropped, and the caller still gets a clean not-found. Turning a 404 +*> the caller already understands into CEPIS-INVALID-RESPONSE over a +*> decoration would be a poor trade. +*> +*> cep_ini and cep_fim must both be eight digits and ceps must be a +*> number, or the whole block is dropped. The span is sparse -- Areal's +*> 118 CEPs are spread over the ~4900 numbers between 25845001 and +*> 25849899 -- so handing a caller the pair without the count invites +*> reading it as a list of valid CEPs, which it is not. +PARSE-FAIXA. + INITIALIZE CEPIS-FAIXA + SET CEPIS-FAIXA-ABSENT TO TRUE + MOVE "faixa" TO JS-KEY + PERFORM GET-MEMBER + IF JS-TYPE NOT = "O" + EXIT PARAGRAPH + END-IF + MOVE JS-VSTART TO WS-FAIXA-FROM + MOVE JS-VEND TO WS-FAIXA-TO + MOVE "Y" TO WS-FAIXA-OK + + MOVE "localidade" TO JS-KEY + PERFORM GET-FAIXA-MEMBER + IF JS-TYPE = "S" AND JS-VALUE-LEN > 0 + MOVE JS-VALUE TO WS-F-LOCALIDADE + ELSE + MOVE "N" TO WS-FAIXA-OK + END-IF + + MOVE "uf" TO JS-KEY + PERFORM GET-FAIXA-MEMBER + IF JS-TYPE = "S" AND JS-VALUE-LEN = 2 + MOVE JS-VALUE TO WS-F-UF + ELSE + MOVE "N" TO WS-FAIXA-OK + END-IF + + MOVE "cep_ini" TO JS-KEY + PERFORM GET-FAIXA-MEMBER + IF JS-TYPE = "S" AND JS-VALUE-LEN = 8 + MOVE JS-VALUE TO WS-F-CEP-INI + ELSE + MOVE "N" TO WS-FAIXA-OK + END-IF + + MOVE "cep_fim" TO JS-KEY + PERFORM GET-FAIXA-MEMBER + IF JS-TYPE = "S" AND JS-VALUE-LEN = 8 + MOVE JS-VALUE TO WS-F-CEP-FIM + ELSE + MOVE "N" TO WS-FAIXA-OK + END-IF + + MOVE "ceps" TO JS-KEY + PERFORM GET-FAIXA-MEMBER + PERFORM CHECK-NUMERIC + IF WS-NUM-OK = "Y" + COMPUTE WS-F-CEPS ROUNDED = FUNCTION NUMVAL (JS-VALUE) + ELSE + MOVE "N" TO WS-FAIXA-OK + END-IF + + IF WS-FAIXA-OK NOT = "Y" + EXIT PARAGRAPH + END-IF + + *> The three below are decoration: a faixa the API sends without + *> them still names the municipality, so they never fail the block. + MOVE SPACES TO WS-F-ESTADO + MOVE "estado" TO JS-KEY + PERFORM GET-FAIXA-MEMBER + IF JS-TYPE = "S" + MOVE JS-VALUE TO WS-F-ESTADO + END-IF + + MOVE SPACES TO WS-F-REGIAO + MOVE "regiao" TO JS-KEY + PERFORM GET-FAIXA-MEMBER + IF JS-TYPE = "S" + MOVE JS-VALUE TO WS-F-REGIAO + END-IF + + MOVE SPACES TO WS-F-IBGE + MOVE "ibge" TO JS-KEY + PERFORM GET-FAIXA-MEMBER + IF JS-TYPE = "S" + MOVE JS-VALUE TO WS-F-IBGE + END-IF + + SET CEPIS-FAIXA-KNOWN TO TRUE + MOVE WS-F-LOCALIDADE TO CEPIS-FAIXA-LOCALIDADE + MOVE WS-F-UF TO CEPIS-FAIXA-UF + MOVE WS-F-ESTADO TO CEPIS-FAIXA-ESTADO + MOVE WS-F-REGIAO TO CEPIS-FAIXA-REGIAO + MOVE WS-F-IBGE TO CEPIS-FAIXA-IBGE + MOVE WS-F-CEP-INI TO CEPIS-FAIXA-CEP-INI + MOVE WS-F-CEP-FIM TO CEPIS-FAIXA-CEP-FIM + MOVE WS-F-CEPS TO CEPIS-FAIXA-CEPS. + +*> ------------------------------------------------------------------- *> FUNCTION NUMVAL answers 0 for text it cannot read, which would turn *> "lat": "not a number" into a coordinate off the coast of Africa. The *> text is therefore checked before it is converted. |