diff --git a/src/pg/carnet-application/carnet-application.service.ts b/src/pg/carnet-application/carnet-application.service.ts index 9a592cb..98178e8 100644 --- a/src/pg/carnet-application/carnet-application.service.ts +++ b/src/pg/carnet-application/carnet-application.service.ts @@ -206,38 +206,34 @@ export class CarnetApplicationService { await client.query('BEGIN'); - function escapePostgresString(str: string): string { + function escapePostgresCompositeField(str: string): string { if (str == null) return ''; - return `"${str.replace(/\\/g, '\\\\').replace(/"/g, '""')}"`; - } - - function escapePostgresValue(val: any): string { - if (val == null || val === '') return ''; // NULL or empty becomes empty string - if (typeof val === 'number') return String(val); // pass numbers as-is - return escapePostgresString(String(val)); // quote and escape strings + return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); } const contactLiterals = body.P_GLTABLE.map(c => { const fields = [ - escapePostgresValue(c.ITEMNO), - escapePostgresValue(c.ITEMDESCRIPTION), - escapePostgresValue(c.ITEMVALUE), - escapePostgresValue(c.NOOFPIECES), - escapePostgresValue(c.ITEMWEIGHT), - escapePostgresValue(c.ITEMWEIGHTUOM), - escapePostgresValue(c.GOODSORIGINCOUNTRY), - ]; + c.ITEMNO ?? '', + c.ITEMDESCRIPTION ?? '', + c.ITEMVALUE ?? '', + c.NOOFPIECES ?? '', + c.ITEMWEIGHT ?? '', + c.ITEMWEIGHTUOM ?? '', + c.GOODSORIGINCOUNTRY ?? '', + ].map(field => escapePostgresCompositeField(String(field))).join(','); - return `"(${fields.join(',')})"`; // ✅ double quotes for composite + return `"(${fields})"`; // ✅ Wrap entire composite in double quotes }); const pgArrayLiteral = `{${contactLiterals.join(',')}}`; const callProcQuery = ` - CALL "CARNETSYS".carnetapplication_pkg_addgenerallistitems($1, $2::"CARNETSYS".gltable[], $3, $4) - `; + CALL "CARNETSYS".carnetapplication_pkg_addgenerallistitems($1, $2::"CARNETSYS".gltable[], $3, $4) +`; + await client.query(callProcQuery, [body.P_HEADERID, pgArrayLiteral, body.P_USERID, cursorName]); + // 🚫 DON'T quote the cursor name in FETCH const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);