added the new invoice flow where new lables added like hsn and part_ amount for gst invoice generation
This commit is contained in:
parent
fd6032f21b
commit
abba8aefdd
@ -15,10 +15,11 @@ import crypto from 'crypto';
|
|||||||
import { DealerClaimDetails } from '../models/DealerClaimDetails';
|
import { DealerClaimDetails } from '../models/DealerClaimDetails';
|
||||||
import { ClaimInvoice } from '../models/ClaimInvoice';
|
import { ClaimInvoice } from '../models/ClaimInvoice';
|
||||||
import { ClaimInvoiceItem } from '../models/ClaimInvoiceItem';
|
import { ClaimInvoiceItem } from '../models/ClaimInvoiceItem';
|
||||||
|
import { ClaimCreditNote } from '../models/ClaimCreditNote';
|
||||||
import { ActivityType } from '../models/ActivityType';
|
import { ActivityType } from '../models/ActivityType';
|
||||||
import { Participant } from '../models/Participant';
|
import { Participant } from '../models/Participant';
|
||||||
import { sanitizeObject, sanitizePermissive } from '../utils/sanitizer';
|
import { sanitizeObject, sanitizePermissive } from '../utils/sanitizer';
|
||||||
import { padDealerCode } from '../utils/helpers';
|
import { buildWfmClaimCsvRow, padDealerCode, WFM_CLAIM_CSV_HEADERS } from '../utils/helpers';
|
||||||
import { costBreakupSchema, closedExpensesSchema, updateEInvoiceSchema, updateIOSchema } from '../validators/dealerClaim.validator';
|
import { costBreakupSchema, closedExpensesSchema, updateEInvoiceSchema, updateIOSchema } from '../validators/dealerClaim.validator';
|
||||||
|
|
||||||
export class DealerClaimController {
|
export class DealerClaimController {
|
||||||
@ -1114,52 +1115,49 @@ export class DealerClaimController {
|
|||||||
const isNonGst = taxationType === 'Non GST' || taxationType === 'Non-GST';
|
const isNonGst = taxationType === 'Non GST' || taxationType === 'Non-GST';
|
||||||
|
|
||||||
// Construct CSV with pipe separator
|
// Construct CSV with pipe separator
|
||||||
const headers = [
|
const headers = isNonGst
|
||||||
'TRNS_UNIQ_NO',
|
? [
|
||||||
'CLAIM_NUMBER',
|
'TRNS_UNIQ_NO',
|
||||||
'INV_NUMBER',
|
'CLAIM_NUMBER',
|
||||||
'DEALER_CODE',
|
'INV_NUMBER',
|
||||||
'IO_NUMBER',
|
'DEALER_CODE',
|
||||||
'CLAIM_DOC_TYP',
|
'IO_NUMBER',
|
||||||
'CLAIM_TYPE',
|
'CLAIM_DOC_TYP',
|
||||||
'CLAIM_DATE',
|
'CLAIM_TYPE',
|
||||||
'CLAIM_AMT'
|
'CLAIM_DATE',
|
||||||
];
|
'CLAIM_AMT'
|
||||||
|
]
|
||||||
if (!isNonGst) {
|
: [...WFM_CLAIM_CSV_HEADERS];
|
||||||
headers.push('GST_AMT', 'GST_PERCENTAGE');
|
|
||||||
}
|
|
||||||
|
|
||||||
const rows = items.map(item => {
|
const rows = items.map(item => {
|
||||||
// For Non-GST, we hide HSN (often stored in transactionCode)
|
if (isNonGst) {
|
||||||
const trnsUniqNo = item.transactionCode || '';
|
const d = new Date(invoice?.invoiceDate || invoice?.createdAt || new Date());
|
||||||
const claimNumber = requestNumber;
|
const claimDate = `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, '0')}${String(d.getDate()).padStart(2, '0')}`;
|
||||||
const invNumber = invoice?.invoiceNumber || '';
|
return [
|
||||||
const dealerCode = padDealerCode(claimDetails?.dealerCode || '');
|
item.transactionCode || '',
|
||||||
const ioNumber = internalOrder?.ioNumber || '';
|
requestNumber,
|
||||||
const claimDocTyp = sapRefNo;
|
invoice?.invoiceNumber || '',
|
||||||
const claimType = claimDetails?.activityType || '';
|
padDealerCode(claimDetails?.dealerCode || ''),
|
||||||
const claimDate = invoice?.createdAt ? new Date(invoice.createdAt).toISOString().split('T')[0] : '';
|
internalOrder?.ioNumber || '',
|
||||||
const claimAmt = item.assAmt;
|
sapRefNo,
|
||||||
|
claimDetails?.activityType || '',
|
||||||
const rowItems = [
|
claimDate,
|
||||||
trnsUniqNo,
|
item.assAmt
|
||||||
claimNumber,
|
].join('|');
|
||||||
invNumber,
|
|
||||||
dealerCode,
|
|
||||||
ioNumber,
|
|
||||||
claimDocTyp,
|
|
||||||
claimType,
|
|
||||||
claimDate,
|
|
||||||
claimAmt
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!isNonGst) {
|
|
||||||
const totalTax = Number(item.igstAmt || 0) + Number(item.cgstAmt || 0) + Number(item.sgstAmt || 0) + Number(item.utgstAmt || 0);
|
|
||||||
rowItems.push(totalTax.toFixed(2), item.gstRt || 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rowItems.join('|');
|
const row = buildWfmClaimCsvRow({
|
||||||
|
item: item as any,
|
||||||
|
requestNumber,
|
||||||
|
invoiceNumber: invoice?.invoiceNumber || '',
|
||||||
|
invoiceDate: (invoice?.invoiceDate as Date) || (invoice?.createdAt as Date) || new Date(),
|
||||||
|
dealerCode: claimDetails?.dealerCode || '',
|
||||||
|
ioNumber: internalOrder?.ioNumber || '',
|
||||||
|
claimDocTyp: sapRefNo,
|
||||||
|
claimType: claimDetails?.activityType || '',
|
||||||
|
});
|
||||||
|
|
||||||
|
return headers.map((key) => String((row as any)[key] ?? '')).join('|');
|
||||||
});
|
});
|
||||||
|
|
||||||
const csvContent = [headers.join('|'), ...rows].join('\n');
|
const csvContent = [headers.join('|'), ...rows].join('\n');
|
||||||
@ -1232,9 +1230,43 @@ export class DealerClaimController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { wfmFileService } = await import('../services/wfmFile.service');
|
const { wfmFileService } = await import('../services/wfmFile.service');
|
||||||
const creditNoteData = await wfmFileService.getCreditNoteDetails(claimDetails.dealerCode, requestNumber, isNonGst);
|
const existingCreditNote = await ClaimCreditNote.findOne({ where: { requestId } });
|
||||||
|
if (existingCreditNote?.sapDocumentNumber || existingCreditNote?.creditNoteNumber) {
|
||||||
|
const payload = [{
|
||||||
|
TRNS_UNIQ_NO: '',
|
||||||
|
CLAIM_NUMBER: requestNumber,
|
||||||
|
DOC_NO: existingCreditNote.sapDocumentNumber || existingCreditNote.creditNoteNumber || '',
|
||||||
|
MSG_TYP: existingCreditNote.status || '',
|
||||||
|
MESSAGE: existingCreditNote.errorMessage || ''
|
||||||
|
}];
|
||||||
|
return ResponseHandler.success(res, payload, 'Credit note data fetched successfully');
|
||||||
|
}
|
||||||
|
|
||||||
return ResponseHandler.success(res, creditNoteData, 'Credit note data fetched successfully');
|
const { filePath, data: creditNoteData } = await wfmFileService.getCreditNoteDetailsWithPath(
|
||||||
|
claimDetails.dealerCode,
|
||||||
|
requestNumber,
|
||||||
|
isNonGst
|
||||||
|
);
|
||||||
|
if (!creditNoteData.length) {
|
||||||
|
return ResponseHandler.success(res, [], 'Credit note data fetched successfully');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Current requirement: process/store a single credit note per request.
|
||||||
|
const firstRow = creditNoteData[0] || {};
|
||||||
|
const existingAmount = existingCreditNote?.creditNoteAmount ?? 0;
|
||||||
|
await ClaimCreditNote.upsert({
|
||||||
|
requestId,
|
||||||
|
creditNoteNumber: firstRow.DOC_NO || firstRow.CREDIT_NOTE_NUMBER || existingCreditNote?.creditNoteNumber || undefined,
|
||||||
|
sapDocumentNumber: firstRow.DOC_NO || firstRow.CREDIT_NOTE_NUMBER || existingCreditNote?.sapDocumentNumber || undefined,
|
||||||
|
status: firstRow.MSG_TYP || existingCreditNote?.status || undefined,
|
||||||
|
errorMessage: firstRow.MESSAGE || existingCreditNote?.errorMessage || undefined,
|
||||||
|
creditNoteFilePath: filePath,
|
||||||
|
creditNoteAmount: Number(firstRow.CLAIM_AMT || firstRow.CREDIT_AMT || existingAmount || 0),
|
||||||
|
confirmedAt: new Date()
|
||||||
|
});
|
||||||
|
wfmFileService.deleteCreditNoteOutgoingFileByPath(filePath);
|
||||||
|
|
||||||
|
return ResponseHandler.success(res, [firstRow], 'Credit note data fetched successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||||
logger.error('[DealerClaimController] Error fetching credit note WFM data:', error);
|
logger.error('[DealerClaimController] Error fetching credit note WFM data:', error);
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import { Document } from '../models/Document';
|
|||||||
import { Dealer } from '../models/Dealer';
|
import { Dealer } from '../models/Dealer';
|
||||||
import { WorkflowService } from './workflow.service';
|
import { WorkflowService } from './workflow.service';
|
||||||
import { DealerClaimApprovalService } from './dealerClaimApproval.service';
|
import { DealerClaimApprovalService } from './dealerClaimApproval.service';
|
||||||
import { generateRequestNumber, padDealerCode } from '../utils/helpers';
|
import { buildWfmClaimCsvRow, generateRequestNumber, padDealerCode } from '../utils/helpers';
|
||||||
import { Priority, WorkflowStatus, ApprovalStatus, ParticipantType } from '../types/common.types';
|
import { Priority, WorkflowStatus, ApprovalStatus, ParticipantType } from '../types/common.types';
|
||||||
import { sapIntegrationService } from './sapIntegration.service';
|
import { sapIntegrationService } from './sapIntegration.service';
|
||||||
import { pwcIntegrationService } from './pwcIntegration.service';
|
import { pwcIntegrationService } from './pwcIntegration.service';
|
||||||
@ -3625,16 +3625,9 @@ export class DealerClaimService {
|
|||||||
isNonGst = taxationType === 'Non GST' || taxationType === 'Non-GST';
|
isNonGst = taxationType === 'Non GST' || taxationType === 'Non-GST';
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatDate = (date: any) => {
|
|
||||||
const d = new Date(date);
|
|
||||||
const year = d.getFullYear();
|
|
||||||
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
||||||
const day = String(d.getDate()).padStart(2, '0');
|
|
||||||
return `${year}${month}${day}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const csvData = invoiceItems.map((item: any) => {
|
const csvData = invoiceItems.map((item: any) => {
|
||||||
const row: any = {
|
if (isNonGst) {
|
||||||
|
return {
|
||||||
TRNS_UNIQ_NO: item.transactionCode || '',
|
TRNS_UNIQ_NO: item.transactionCode || '',
|
||||||
CLAIM_NUMBER: requestNumber,
|
CLAIM_NUMBER: requestNumber,
|
||||||
INV_NUMBER: invoice.invoiceNumber || '',
|
INV_NUMBER: invoice.invoiceNumber || '',
|
||||||
@ -3642,17 +3635,24 @@ export class DealerClaimService {
|
|||||||
IO_NUMBER: internalOrder?.ioNumber || '',
|
IO_NUMBER: internalOrder?.ioNumber || '',
|
||||||
CLAIM_DOC_TYP: sapRefNo,
|
CLAIM_DOC_TYP: sapRefNo,
|
||||||
CLAIM_TYPE: claimDetails.activityType,
|
CLAIM_TYPE: claimDetails.activityType,
|
||||||
CLAIM_DATE: formatDate(invoice.invoiceDate || new Date()),
|
CLAIM_DATE: (() => {
|
||||||
|
const d = new Date(invoice.invoiceDate || new Date());
|
||||||
|
return `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, '0')}${String(d.getDate()).padStart(2, '0')}`;
|
||||||
|
})(),
|
||||||
CLAIM_AMT: item.assAmt
|
CLAIM_AMT: item.assAmt
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!isNonGst) {
|
|
||||||
const totalTax = Number(item.igstAmt || 0) + Number(item.cgstAmt || 0) + Number(item.sgstAmt || 0) + Number(item.utgstAmt || 0);
|
|
||||||
row.GST_AMT = totalTax.toFixed(2);
|
|
||||||
row.GST_PERCENTAGE = item.gstRt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return row;
|
return buildWfmClaimCsvRow({
|
||||||
|
item,
|
||||||
|
requestNumber,
|
||||||
|
invoiceNumber: invoice.invoiceNumber || '',
|
||||||
|
invoiceDate: (invoice.invoiceDate as Date) || new Date(),
|
||||||
|
dealerCode: claimDetails.dealerCode,
|
||||||
|
ioNumber: internalOrder?.ioNumber || '',
|
||||||
|
claimDocTyp: sapRefNo,
|
||||||
|
claimType: claimDetails.activityType || '',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await wfmFileService.generateIncomingClaimCSV(csvData, `CN_${padDealerCode(claimDetails.dealerCode)}_${requestNumber}.csv`, isNonGst);
|
await wfmFileService.generateIncomingClaimCSV(csvData, `CN_${padDealerCode(claimDetails.dealerCode)}_${requestNumber}.csv`, isNonGst);
|
||||||
|
|||||||
@ -154,21 +154,67 @@ export class WFMFileService {
|
|||||||
return path.join(this.basePath, targetPath, fileName);
|
return path.join(this.basePath, targetPath, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getOutgoingClaimsDir(isNonGst: boolean = false): string {
|
||||||
|
const targetPath = isNonGst ? this.outgoingNonGstClaimsPath : this.outgoingGstClaimsPath;
|
||||||
|
return path.join(this.basePath, targetPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build outgoing credit note file path for a dealer + request.
|
||||||
|
*/
|
||||||
|
getCreditNoteOutgoingFilePath(dealerCode: string, requestNumber: string, isNonGst: boolean = false): { fileName: string; filePath: string } {
|
||||||
|
const dealer = String(dealerCode || '').trim();
|
||||||
|
const paddedDealer = dealer.padStart(6, '0');
|
||||||
|
const exactCandidates = [
|
||||||
|
`CN_${paddedDealer}_${requestNumber}.csv`,
|
||||||
|
`CN_${dealer}_${requestNumber}.csv`,
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const candidate of exactCandidates) {
|
||||||
|
const candidatePath = this.getOutgoingPath(candidate, isNonGst);
|
||||||
|
if (fs.existsSync(candidatePath)) {
|
||||||
|
return { fileName: candidate, filePath: candidatePath };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last fallback: pick any CN_*_<requestNumber>.csv from target outgoing folder.
|
||||||
|
const outgoingDir = this.getOutgoingClaimsDir(isNonGst);
|
||||||
|
if (fs.existsSync(outgoingDir)) {
|
||||||
|
const escapedReq = requestNumber.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
const reqFileRegex = new RegExp(`^CN_.*_${escapedReq}\\.csv$`, 'i');
|
||||||
|
const matched = fs.readdirSync(outgoingDir).find((name) => reqFileRegex.test(name));
|
||||||
|
if (matched) {
|
||||||
|
return { fileName: matched, filePath: path.join(outgoingDir, matched) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep deterministic default for callers when no file exists yet.
|
||||||
|
const fileName = exactCandidates[0];
|
||||||
|
return { fileName, filePath: this.getOutgoingPath(fileName, isNonGst) };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get credit note details from outgoing CSV
|
* Get credit note details from outgoing CSV
|
||||||
*/
|
*/
|
||||||
async getCreditNoteDetails(dealerCode: string, requestNumber: string, isNonGst: boolean = false): Promise<any[]> {
|
async getCreditNoteDetails(dealerCode: string, requestNumber: string, isNonGst: boolean = false): Promise<any[]> {
|
||||||
const fileName = `CN_${String(dealerCode).padStart(6, '0')}_${requestNumber}.csv`;
|
const { data } = await this.getCreditNoteDetailsWithPath(dealerCode, requestNumber, isNonGst);
|
||||||
const filePath = this.getOutgoingPath(fileName, isNonGst);
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get credit note details and resolved file path from outgoing CSV.
|
||||||
|
*/
|
||||||
|
async getCreditNoteDetailsWithPath(dealerCode: string, requestNumber: string, isNonGst: boolean = false): Promise<{ fileName: string; filePath: string; data: any[] }> {
|
||||||
|
const { fileName, filePath } = this.getCreditNoteOutgoingFilePath(dealerCode, requestNumber, isNonGst);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!fs.existsSync(filePath)) {
|
if (!fs.existsSync(filePath)) {
|
||||||
return [];
|
return { fileName, filePath, data: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
||||||
const lines = fileContent.split('\n').filter(line => line.trim() !== '');
|
const lines = fileContent.split('\n').filter(line => line.trim() !== '');
|
||||||
if (lines.length <= 1) return []; // Only headers or empty
|
if (lines.length <= 1) return { fileName, filePath, data: [] }; // Only headers or empty
|
||||||
|
|
||||||
const headers = lines[0].split('|');
|
const headers = lines[0].split('|');
|
||||||
const data = lines.slice(1).map(line => {
|
const data = lines.slice(1).map(line => {
|
||||||
@ -180,10 +226,25 @@ export class WFMFileService {
|
|||||||
return row;
|
return row;
|
||||||
});
|
});
|
||||||
|
|
||||||
return data;
|
return { fileName, filePath, data };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[WFMFileService] Error reading credit note CSV: ${fileName}`, error);
|
logger.error(`[WFMFileService] Error reading credit note CSV: ${fileName}`, error);
|
||||||
return [];
|
return { fileName, filePath, data: [] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an outgoing credit note file once it has been persisted.
|
||||||
|
*/
|
||||||
|
deleteCreditNoteOutgoingFileByPath(filePath: string): void {
|
||||||
|
try {
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
fs.unlinkSync(filePath);
|
||||||
|
logger.info(`[WFMFileService] Deleted processed credit note CSV: ${filePath}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[WFMFileService] Error deleting processed credit note CSV:', filePath, error);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -115,3 +115,93 @@ export const padDealerCode = (dealerCode: string | number): string => {
|
|||||||
if (dealerCode === null || dealerCode === undefined) return '';
|
if (dealerCode === null || dealerCode === undefined) return '';
|
||||||
return String(dealerCode).padStart(6, '0');
|
return String(dealerCode).padStart(6, '0');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WFM incoming claim CSV headers in required fixed order.
|
||||||
|
*/
|
||||||
|
export const WFM_CLAIM_CSV_HEADERS = [
|
||||||
|
'TRNS_UNIQ_NO',
|
||||||
|
'CLAIM_NUMBER',
|
||||||
|
'INV_NUMBER',
|
||||||
|
'INV_DATE',
|
||||||
|
'DEALER_CODE',
|
||||||
|
'IO_NUMBER',
|
||||||
|
'CLAIM_DOC_TYP',
|
||||||
|
'CLAIM_TYPE',
|
||||||
|
'CLAIM_DATE',
|
||||||
|
'HSN_CODE',
|
||||||
|
'SAC_CODE',
|
||||||
|
'PART_AMT',
|
||||||
|
'LABOUR_AMT',
|
||||||
|
'GST_AMT',
|
||||||
|
'GST_PERCENTAGE',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
type WfmInvoiceItemLike = {
|
||||||
|
transactionCode?: string;
|
||||||
|
hsnCd?: string;
|
||||||
|
assAmt?: number | string;
|
||||||
|
gstRt?: number | string;
|
||||||
|
igstAmt?: number | string;
|
||||||
|
cgstAmt?: number | string;
|
||||||
|
sgstAmt?: number | string;
|
||||||
|
utgstAmt?: number | string;
|
||||||
|
isServc?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type BuildWfmRowInput = {
|
||||||
|
item: WfmInvoiceItemLike;
|
||||||
|
requestNumber: string;
|
||||||
|
invoiceNumber: string;
|
||||||
|
invoiceDate: Date;
|
||||||
|
dealerCode: string;
|
||||||
|
ioNumber: string;
|
||||||
|
claimDocTyp: string;
|
||||||
|
claimType: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build one WFM incoming claim CSV row.
|
||||||
|
* Business rule:
|
||||||
|
* - Service line -> SAC_CODE + LABOUR_AMT, keep HSN_CODE + PART_AMT empty
|
||||||
|
* - Material line -> HSN_CODE + PART_AMT, keep SAC_CODE + LABOUR_AMT empty
|
||||||
|
*/
|
||||||
|
export const buildWfmClaimCsvRow = ({
|
||||||
|
item,
|
||||||
|
requestNumber,
|
||||||
|
invoiceNumber,
|
||||||
|
invoiceDate,
|
||||||
|
dealerCode,
|
||||||
|
ioNumber,
|
||||||
|
claimDocTyp,
|
||||||
|
claimType,
|
||||||
|
}: BuildWfmRowInput): Record<(typeof WFM_CLAIM_CSV_HEADERS)[number], string | number> => {
|
||||||
|
const d = new Date(invoiceDate);
|
||||||
|
const invDate = `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, '0')}${String(d.getDate()).padStart(2, '0')}`;
|
||||||
|
const normalizedIsService = String(item.isServc || '').toUpperCase() === 'Y';
|
||||||
|
const hsnOrSac = item.hsnCd || '';
|
||||||
|
const assesableAmount = Number(item.assAmt || 0);
|
||||||
|
const totalTax =
|
||||||
|
Number(item.igstAmt || 0) +
|
||||||
|
Number(item.cgstAmt || 0) +
|
||||||
|
Number(item.sgstAmt || 0) +
|
||||||
|
Number(item.utgstAmt || 0);
|
||||||
|
|
||||||
|
return {
|
||||||
|
TRNS_UNIQ_NO: item.transactionCode || '',
|
||||||
|
CLAIM_NUMBER: requestNumber || '',
|
||||||
|
INV_NUMBER: invoiceNumber || '',
|
||||||
|
INV_DATE: invDate,
|
||||||
|
DEALER_CODE: padDealerCode(dealerCode || ''),
|
||||||
|
IO_NUMBER: ioNumber || '',
|
||||||
|
CLAIM_DOC_TYP: claimDocTyp || '',
|
||||||
|
CLAIM_TYPE: claimType || '',
|
||||||
|
CLAIM_DATE: invDate,
|
||||||
|
HSN_CODE: normalizedIsService ? '' : hsnOrSac,
|
||||||
|
SAC_CODE: normalizedIsService ? hsnOrSac : '',
|
||||||
|
PART_AMT: normalizedIsService ? '' : assesableAmount.toFixed(2),
|
||||||
|
LABOUR_AMT: normalizedIsService ? assesableAmount.toFixed(2) : '',
|
||||||
|
GST_AMT: totalTax.toFixed(2),
|
||||||
|
GST_PERCENTAGE: item.gstRt ?? '',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user