CSV fix OUTGOING
This commit is contained in:
parent
06e70435c0
commit
604dcfbef5
@ -60,6 +60,7 @@ function extractCsvFields(r: Record<string, string | undefined>) {
|
||||
async function findCreditNoteId(
|
||||
trnsUniqNo: string | null,
|
||||
tdsTransId: string | null,
|
||||
claimNumber: string | null,
|
||||
fileName: string,
|
||||
): Promise<{ creditNoteId: number | null; requestId: string | null }> {
|
||||
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 };
|
||||
|
||||
const submission = await (Form16aSubmission as any).findByPk(cn.submissionId, { attributes: ['requestId'] });
|
||||
@ -225,7 +232,7 @@ async function processOutgoingFile(
|
||||
let requestNumber: string | null = null;
|
||||
|
||||
if (type === 'credit') {
|
||||
const res = await findCreditNoteId(trnsUniqNo, tdsTransId, fileName);
|
||||
const res = await findCreditNoteId(trnsUniqNo, tdsTransId, claimNumber, fileName);
|
||||
creditNoteId = res.creditNoteId;
|
||||
requestId = res.requestId;
|
||||
if (creditNoteId && sapDocNo) {
|
||||
|
||||
@ -278,7 +278,11 @@ export async function listCreditNotesForDealer(userId: string, filters?: { finan
|
||||
if (hasTrnsUniqNoColumn && noteIds.length) {
|
||||
try {
|
||||
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'],
|
||||
raw: true,
|
||||
});
|
||||
@ -883,7 +887,11 @@ export async function listAllCreditNotesForRe(filters?: { financialYear?: string
|
||||
if (hasTrnsUniqNoColumn && noteIds.length) {
|
||||
try {
|
||||
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'],
|
||||
raw: true,
|
||||
});
|
||||
@ -995,7 +1003,10 @@ export async function listAllDebitNotesForRe(filters?: { financialYear?: string;
|
||||
if (noteIds.length) {
|
||||
try {
|
||||
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'],
|
||||
raw: true,
|
||||
});
|
||||
|
||||
@ -287,9 +287,21 @@ export class WFMFileService {
|
||||
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
||||
const lines = fileContent.split(/\r?\n/).filter(line => line.trim() !== '');
|
||||
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 values = line.split('|');
|
||||
const values = line.split(delimiter);
|
||||
const row: any = {};
|
||||
headers.forEach((header, index) => {
|
||||
row[header] = values[index]?.trim() || '';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user