mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-06 10:03:38 +00:00
fix(eims): resolve Addis Ababa addresses against MoR's sub-city tier
MoR's location master has no zone level in a chartered city: CITY_NAME is the sub-city and LOCALITY_DESC is the numbered woreda. e-Trade fills the gap by repeating the region in ZONE, pushing the sub-city into CITY_NAME and the woreda number into LOCALITY_DESC, so every Addis Ababa buyer failed CITY_NAME lookup and could not be filed at all. Retry one level down when ZONE repeats the region, accepting it only when both shifted levels resolve exactly — an unknown zone still fails with its own message. Match a zero-padded 07 against MoR's own WOREDA 7 spelling, and add the reviewed AMAHARA / KOLFIE KERANIYO / MISRAK SHOA aliases. Verified against the dev database: 2 of 40 companies resolved before, 31 after.
This commit is contained in:
100
apps/edr-freight-api/src/scripts/seed-mor-test-buyers.ts
Normal file
100
apps/edr-freight-api/src/scripts/seed-mor-test-buyers.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { AppDataSource } from "../data-source";
|
||||
|
||||
/**
|
||||
* Seeds the 30 test taxpayers the Ministry of Revenues issued for the EIMS/BSP
|
||||
* **non-self buyer** certification run — the checklist item that needs a real
|
||||
* invoice filed against a buyer that is not EDR itself.
|
||||
*
|
||||
* Every field comes from MoR's own roster, except the two location codes, which
|
||||
* do not survive contact with the Ministry's own location master:
|
||||
*
|
||||
* - MoR's sheet gives `Region = "1"`. `PARISH_NO 1` is not an Ethiopian region
|
||||
* at all (it is Djibouti), so the region is stored by name — `Bole` is an
|
||||
* Addis Ababa sub-city, which fixes the region unambiguously (PARISH_NO 13).
|
||||
* - MoR's sheet gives `City = "101"`, which is GOFA ZONE in SNNPRS. The buyer
|
||||
* is in Bole, so the sub-city is stored by name (CITY_NO 78).
|
||||
*
|
||||
* In other words MoR does not validate the geographic codes it sends itself;
|
||||
* these rows carry the addresses that actually resolve. The roster carries no
|
||||
* woreda, so every row takes `NO WOREDA-144` — MoR's *own* "not specified"
|
||||
* locality under BOLE (LOCALITY_NO 574), the same code EDR's static seller
|
||||
* details already file under. Nothing here is invented.
|
||||
*
|
||||
* Idempotent: `ON CONFLICT (tin) DO NOTHING`. TIN 0089238373 is already on file
|
||||
* as a real customer (Afri Software Solutions) and is deliberately left alone.
|
||||
*/
|
||||
|
||||
/**
|
||||
* `[TIN, phone, legal name, email, kebele?, house number?]`, verbatim from MoR's roster. The two
|
||||
* trailing fields default to the values 22 of the 30 rows share.
|
||||
*/
|
||||
const KEBELE = "Near Bole Airport";
|
||||
const HOUSE_NO = "123B";
|
||||
|
||||
const MOR_TEST_BUYERS: Array<[string, string, string, string, string?, string?]> = [
|
||||
["0089238373", "251911091245", "Taxpayer A", "codethicaet@gmail.com", "Near Airport", "101"],
|
||||
["0054864576", "251911091245", "Taxpayer B", "shehir8@gmail.com", "Near Airport"],
|
||||
["0049056594", "251911091245", "Taxpayer C", "teme@odooethiopia.com", "Near Airport"],
|
||||
["0059819904", "251911091245", "Taxpayer D", "rubiethoplc@gmail.com", "Near Airport"],
|
||||
["0000018932", "251911091245", "Taxpayer E", "amanuelephremedu@gmail.com", "Near Airport"],
|
||||
["0088683375", "251911091245", "Taxpayer F", "ermiastegegn576@gmail.com", "Near Airport"],
|
||||
["0068421445", "251911091245", "Taxpayer G", "qelemmeda@gmail.com", "Near Airport"],
|
||||
["0004404844", "251911091245", "Taxpayer H", "dagnegamu24@gmail.com"],
|
||||
["0000037187", "251911091245", "Taxpayer I", "deresr.belay@gmail.com"],
|
||||
["0050167460", "251911091245", "Taxpayer J", "sera2013ec@gmail.com"],
|
||||
["0079690836", "251909978781", "Taxpayer K", "asmeradefa@gmail.com"],
|
||||
["0068180813", "251944310004", "Taxpayer L", "hailelt@gmail.com"],
|
||||
["0083907363", "251944310004", "Taxpayer M", "dawitfissha1@gmail.com"],
|
||||
["0089032785", "251944310004", "Taxpayer N", "tewahido11@gmail.com"],
|
||||
["0003826418", "251944310004", "Taxpayer O", "alemayehu.t@marakisoft.com"],
|
||||
["0053374665", "251944310004", "Taxpayer P", "getlelaw@gmail.com"],
|
||||
["0016175194", "251911463482", "Taxpayer Q", "abiye.abi@gmail.com", "Near Airport"],
|
||||
["0094542975", "251911463482", "Taxpayer R", "abelgebreananya@gmail.com"],
|
||||
// MoR's roster carries an 11-digit phone here; kept verbatim rather than "corrected".
|
||||
["0088514835", "25191124368", "Taxpayer S", "ewnget77@gmail.com"],
|
||||
["0076217301", "251960403750", "Taxpayer T", "merontamirat.redcloud@gmail.com"],
|
||||
["0003826419", "251911516507", "Taxpayer 322", "alemayehu.t@marakisoft.com"],
|
||||
["0056961577", "251929020729", "Taxpayer 323", "ltictsolution@gmail.com", undefined, "1234B"],
|
||||
["0090853345", "251911376145", "Taxpayer 324", "kidusgoshu2be@gmail.com"],
|
||||
["0000028643", "251988899003", "Taxpayer 325", "mesaysisay10@gmail.com"],
|
||||
["0057751727", "251911437928", "Taxpayer 326", "zewdugeta@gmail.com"],
|
||||
["0082549522", "251907256543", "Taxpayer 327", "brookgm2@gmail.com"],
|
||||
["0093283311", "251953915419", "Taxpayer 328", "henock.ad@gmail.com"],
|
||||
["0078795374", "251911091245", "Taxpayer 329", "danielltadesse@gmail.com"],
|
||||
["0093346931", "251935724920", "Taxpayer 330", "halidabd63@gmail.com"],
|
||||
["0040887091", "251913792959", "Taxpayer 331", "milextech@gmail.com"],
|
||||
];
|
||||
|
||||
async function seedMorTestBuyers(): Promise<void> {
|
||||
await AppDataSource.initialize();
|
||||
try {
|
||||
for (const [tin, phone, name, email, kebele, houseNo] of MOR_TEST_BUYERS) {
|
||||
await AppDataSource.query(
|
||||
`INSERT INTO freight.companies
|
||||
(name, type, kind, status, tin, country, region, zone, woreda, kebele,
|
||||
house_no, phone, email)
|
||||
VALUES ($1, 'customer', 'commercial', 'active', $2, 'Ethiopia', 'Addis Ababa', 'Bole',
|
||||
'NO WOREDA-144', $3, $4, $5, $6)
|
||||
ON CONFLICT (tin) DO NOTHING`,
|
||||
[name, tin, kebele ?? KEBELE, houseNo ?? HOUSE_NO, phone, email],
|
||||
);
|
||||
}
|
||||
|
||||
const summary = await AppDataSource.query(
|
||||
`SELECT count(*)::int AS on_file,
|
||||
count(*) FILTER (WHERE name LIKE 'Taxpayer %')::int AS seeded
|
||||
FROM freight.companies
|
||||
WHERE tin = ANY($1::text[])`,
|
||||
[MOR_TEST_BUYERS.map(([tin]) => tin)],
|
||||
);
|
||||
console.table(summary);
|
||||
console.log("Seeded MoR EIMS/BSP test buyers.");
|
||||
} finally {
|
||||
await AppDataSource.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
seedMorTestBuyers().catch((err) => {
|
||||
console.error("MoR test buyer seed failed:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user