CSV fix OUTGOING

This commit is contained in:
Aaditya Jaiswal 2026-03-20 12:07:33 +05:30
parent 06e70435c0
commit 604dcfbef5
3 changed files with 36 additions and 6 deletions

View File

@ -60,6 +60,7 @@ function extractCsvFields(r: Record<string, string | undefined>) {
async function findCreditNoteId( async function findCreditNoteId(
trnsUniqNo: string | null, trnsUniqNo: string | null,
tdsTransId: string | null, tdsTransId: string | null,
claimNumber: string | null,
fileName: string, fileName: string,
): Promise<{ creditNoteId: number | null; requestId: string | null }> { ): Promise<{ creditNoteId: number | null; requestId: string | null }> {
const CN = Form16CreditNote as any; const CN = Form16CreditNote as any;
@ -93,6 +94,12 @@ async function findCreditNoteId(
} }
} }
// 4. CLAIM_NUMBER = credit note number (seen in some SAP/WFM exports)
if (!cn && claimNumber) {
cn = await CN.findOne({ where: { creditNoteNumber: claimNumber }, attributes: ['id', 'submissionId'] });
if (cn) logger.info(`[Form16 SAP Job] Credit match via CLAIM_NUMBER=${claimNumber} → credit_note id=${cn.id}`);
}
if (!cn) return { creditNoteId: null, requestId: null }; if (!cn) return { creditNoteId: null, requestId: null };
const submission = await (Form16aSubmission as any).findByPk(cn.submissionId, { attributes: ['requestId'] }); const submission = await (Form16aSubmission as any).findByPk(cn.submissionId, { attributes: ['requestId'] });
@ -225,7 +232,7 @@ async function processOutgoingFile(
let requestNumber: string | null = null; let requestNumber: string | null = null;
if (type === 'credit') { if (type === 'credit') {
const res = await findCreditNoteId(trnsUniqNo, tdsTransId, fileName); const res = await findCreditNoteId(trnsUniqNo, tdsTransId, claimNumber, fileName);
creditNoteId = res.creditNoteId; creditNoteId = res.creditNoteId;
requestId = res.requestId; requestId = res.requestId;
if (creditNoteId && sapDocNo) { if (creditNoteId && sapDocNo) {

View File

@ -278,7 +278,11 @@ export async function listCreditNotesForDealer(userId: string, filters?: { finan
if (hasTrnsUniqNoColumn && noteIds.length) { if (hasTrnsUniqNoColumn && noteIds.length) {
try { try {
const sapRows = await (Form16SapResponse as any).findAll({ const sapRows = await (Form16SapResponse as any).findAll({
where: { type: 'credit', creditNoteId: { [Op.in]: noteIds }, storageUrl: { [Op.ne]: null } }, where: {
type: 'credit',
creditNoteId: { [Op.in]: noteIds },
[Op.or]: [{ storageUrl: { [Op.ne]: null } }, { sapDocumentNumber: { [Op.ne]: null } }],
},
attributes: ['creditNoteId'], attributes: ['creditNoteId'],
raw: true, raw: true,
}); });
@ -883,7 +887,11 @@ export async function listAllCreditNotesForRe(filters?: { financialYear?: string
if (hasTrnsUniqNoColumn && noteIds.length) { if (hasTrnsUniqNoColumn && noteIds.length) {
try { try {
const sapRows = await (Form16SapResponse as any).findAll({ const sapRows = await (Form16SapResponse as any).findAll({
where: { type: 'credit', creditNoteId: { [Op.in]: noteIds }, storageUrl: { [Op.ne]: null } }, where: {
type: 'credit',
creditNoteId: { [Op.in]: noteIds },
[Op.or]: [{ storageUrl: { [Op.ne]: null } }, { sapDocumentNumber: { [Op.ne]: null } }],
},
attributes: ['creditNoteId'], attributes: ['creditNoteId'],
raw: true, raw: true,
}); });
@ -995,7 +1003,10 @@ export async function listAllDebitNotesForRe(filters?: { financialYear?: string;
if (noteIds.length) { if (noteIds.length) {
try { try {
const sapRows = await (Form16DebitNoteSapResponse as any).findAll({ const sapRows = await (Form16DebitNoteSapResponse as any).findAll({
where: { debitNoteId: { [Op.in]: noteIds }, storageUrl: { [Op.ne]: null } }, where: {
debitNoteId: { [Op.in]: noteIds },
[Op.or]: [{ storageUrl: { [Op.ne]: null } }, { sapDocumentNumber: { [Op.ne]: null } }],
},
attributes: ['debitNoteId'], attributes: ['debitNoteId'],
raw: true, raw: true,
}); });

View File

@ -287,9 +287,21 @@ export class WFMFileService {
const fileContent = fs.readFileSync(filePath, 'utf-8'); const fileContent = fs.readFileSync(filePath, 'utf-8');
const lines = fileContent.split(/\r?\n/).filter(line => line.trim() !== ''); const lines = fileContent.split(/\r?\n/).filter(line => line.trim() !== '');
if (lines.length <= 1) return []; if (lines.length <= 1) return [];
const headers = lines[0].split('|').map(h => h.trim());
// SAP/WFM responses are expected to use pipe ('|'), but some environments may export
// with comma/semicolon or with spaces in header names. Normalize both delimiter + headers.
const headerLine = lines[0] || '';
const delimiter = headerLine.includes('|') ? '|' : headerLine.includes(';') ? ';' : ',';
const normalizeHeaderKey = (h: string) =>
h
.trim()
.toUpperCase()
.replace(/\s+/g, '_') // 'DOC NO' -> 'DOC_NO'
.replace(/[^A-Z0-9_]/g, '_'); // keep only safe chars for matching
const headers = headerLine.split(delimiter).map(normalizeHeaderKey);
const data = lines.slice(1).map(line => { const data = lines.slice(1).map(line => {
const values = line.split('|'); const values = line.split(delimiter);
const row: any = {}; const row: any = {};
headers.forEach((header, index) => { headers.forEach((header, index) => {
row[header] = values[index]?.trim() || ''; row[header] = values[index]?.trim() || '';