From f7be33eaaf4436ef5c47a6582b2096f01b677237 Mon Sep 17 00:00:00 2001 From: Hagernesh Date: Mon, 17 Aug 2026 18:43:26 +0000 Subject: [PATCH] feat(eims): alias bare Addis Ababa sub-city names to the CSV's woreda codes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Confirmed live 2026-08-17: buyer profiles store just the sub-city name ("Bole", "Arada") as their woreda, never the source CSV's specific example-woreda name ("Bole Woreda 01") — hit for three different buyers in a row (Bole, Arada, Lemi Kura) before any got past this check. Since the CSV lists exactly one representative woreda per Addis sub-city, alias the bare name to that same code instead of waiting on a fuller table — use what's already been supplied first. Lemi Kura itself isn't in the source CSV at all (one of Addis Ababa's newer sub-cities) — still needs its real code from MoR. --- .../src/config/eims.config.spec.ts | 15 +++++++++++++ .../src/config/ethiopia-geo-codes.ts | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/apps/edr-freight-api/src/config/eims.config.spec.ts b/apps/edr-freight-api/src/config/eims.config.spec.ts index 60ee33e1b..127b3ea62 100644 --- a/apps/edr-freight-api/src/config/eims.config.spec.ts +++ b/apps/edr-freight-api/src/config/eims.config.spec.ts @@ -113,4 +113,19 @@ describe("eims.config — baked-in Ethiopia region/zone/woreda codes", () => { }, ); }); + + it("resolves the bare Addis Ababa sub-city name a buyer profile actually stores, not the CSV's example-woreda name", () => { + withEnv( + { ...REQUIRED, EIMS_PRIVATE_KEY: "x", EIMS_CERTIFICATE_PATH: "/dev/null" }, + () => { + const codes = eimsConfigFactory().invoice.buyerWeredaCodes; + expect(codes.Bole).toBe("01"); + expect(codes.Arada).toBe("01"); + expect(codes.Kirkos).toBe("01"); + expect(codes.Yeka).toBe("01"); + expect(codes["Nifas Silk Lafto"]).toBe("13"); + expect(codes["Nefas Silk-Lafto"]).toBe("13"); + }, + ); + }); }); diff --git a/apps/edr-freight-api/src/config/ethiopia-geo-codes.ts b/apps/edr-freight-api/src/config/ethiopia-geo-codes.ts index f7257e045..ca48a7c5f 100644 --- a/apps/edr-freight-api/src/config/ethiopia-geo-codes.ts +++ b/apps/edr-freight-api/src/config/ethiopia-geo-codes.ts @@ -137,3 +137,24 @@ export const ETHIOPIA_REGION_CODES: Record = buildMap((r) => [r[ /** Zone name → code. Fed into `buyerCityCodes` — EIMS's "City" is really the buyer's zone. */ export const ETHIOPIA_ZONE_CODES: Record = buildMap((r) => [r[1], r[4]]); export const ETHIOPIA_WOREDA_CODES: Record = buildMap((r) => [r[2], r[5]]); + +/** + * Buyer records commonly store just the bare Addis Ababa sub-city name ("Bole", "Arada") as their + * woreda, not the source CSV's specific example-woreda name ("Bole Woreda 01") — confirmed live + * 2026-08-17 across three different buyers before any of them actually got past this check. Since + * the CSV lists exactly one representative woreda per Addis sub-city, alias the bare name to that + * same code rather than wait on a fuller table. + */ +const ADDIS_SUBCITY_ALIASES: Array<[bareName: string, csvZoneName: string]> = [ + ["Bole", "Bole Sub-City"], + ["Kirkos", "Kirkos Sub-City"], + ["Nifas Silk Lafto", "Nifas Silk Lafto"], + // Matches EIMS_BUYER_WEREDA_CODES' own existing spelling in .env — same zone, different hyphenation. + ["Nefas Silk-Lafto", "Nifas Silk Lafto"], + ["Yeka", "Yeka Sub-City"], + ["Arada", "Arada Sub-City"], +]; +for (const [bareName, csvZoneName] of ADDIS_SUBCITY_ALIASES) { + const row = ROWS.find((r) => r[1] === csvZoneName); + if (row && !(bareName in ETHIOPIA_WOREDA_CODES)) ETHIOPIA_WOREDA_CODES[bareName] = row[5]; +}