Note:
To access the LATAM File Builder SuiteApp documentation in Brazilian Portuguese (Português do Brasil), see LATAM File Builder.
A custom implementation of the File Processing plug-in type (customscript_lfb_pl_type_file_processing
) enables you to manipulate the files that you want to build or import into NetSuite.
By creating a plug-in implementation, you can run a custom logic at different points of the process and modify the file based on its properties or content. The same plug-in supports functions from both the build and import processes. Because the functions are specific to each process, you can implement the functions of one process without interfering with the other.
Note:
All functions are optional, but if you are customizing a file import process, you should implement the processImportRow(context) function.
NetSuite starts running the functions in the plug-in implementation when a map/reduce script identifies a pending file processing request. Select SuiteApps have the ability to create these requests and you can customize how they process files to fit your business needs.
Create a JavaScript file compatible with SuiteScript 2.1 for the custom plug-in implementation.
The following table provides sample codes based on an implementation of the file processing plug-in from the Brazil Reports SuiteApp. This plug-in implementation generates reports for Brazil's Sistema Público de Escrituração Digital (SPED) from the SPED File record. In Brazil Reports, the SPED File record is responsible for the creation of the file processing request.
For more information, see Brazil Reports and Statutory Reports for Brazil.
Interface Function
|
Description
|
afterGetPendingRequest(context)
|
Updates the Status field on the SPED File record to Processing as the system starts processing the request.
export function afterGetPendingRequest(requestParams: FileProcessingRequestDetails): void {
const fieldValues: RecordInstanceFieldValue[] = [];
fieldValues.push({
id: SpedFileFields.Status,
value: getSpedStatusByScriptId(SpedFileStatusEnum.Processing)
});
updateSpedFileRecord(requestParams.sourceRecordId, fieldValues);
}
|
getPendingRequestFailure(context)
|
Updates the Status field on the SPED File record to Failed and the Generation Details field with the content of the error message.
export function getPendingRequestFailure(context: GetPendingRequestFailureContext): void {
const fieldValues: RecordInstanceFieldValue[] = [];
fieldValues.push({
id: SpedFileFields.Status,
value: getSpedStatusByScriptId(SpedFileStatusEnum.Failed)
});
fieldValues.push({
id: SpedFileFields.GenerationDetails,
value: context.errorMessage
});
updateSpedFileRecord(context.sourceRecordId, fieldValues);
}
|
processSourceData(context)
|
Changes the data returned by the section source query.
In this scenario, the function combines the CST ICMS, ICMS Rate and CFOP values, a formatting that cannot be obtained through a query alone.
export function processSourceData(
source: efdLib.SectionSource,
_request: efdLib.FileProcessingRequestParams,
data: any[]
): any {
data.forEach((row) => {
const additionalTaxDetails = JSON.parse(row.custrecord_fte_addtaxcalcdet_lt_json);
additionalTaxDetails.lines.forEach((lineTaxDetail) => {
if (row.taxcode && Number(row.line) === Number(lineTaxDetail.lineNumber)) {
lineTaxDetail.taxesLineInformation
.filter((fiterTaxLineInfo) => {
return (
row.taxcode === fiterTaxLineInfo.taxCodeId &&
fiterTaxLineInfo.taxRateParameterType.indexOf("CST_") > -1
);
})
.forEach((lineInformation) => {
//SQL Query is filtering by ICMS_ST_BR
row.custrecord_fte_paramtype_t_key = getCst(
lineInformation.taxRateParameterType.split("_")[1],
lineInformation.taxCodeName
);
});
}
});
row.custrecord_fte_addtaxcalcdet_lt_json = null;
[
"unitprice",
"amountuniticmsnaopconv",
"amountuniticmsopconv",
"amountuniticmsopinvconv",
"amountuniticmsstinvconv",
"amountunitfcpicmsstinvconv",
"amountuniticmsstconvrest",
"amountunitfcpstconvrest",
"amountuniticmsstconvcompl",
"amountunitfcpstconvcompl"
].forEach((column) => {
if (typeof row[column] == "number" && Number(row[column]) < 0) {
row[column] = 0;
}
});
});
return data;
}
|
beforeSaveOutputFileWithOpt(context)
|
Adds section source counters and the total of rows to the output file.
export function beforeSaveOutputFileWithOpt(
options: efdLib.BeforeSaveOutputFileOptions
): efdLib.BeforeSaveOutputFileResult {
const outputFileRows = options.outputFileContents.split(options.fileLayout.lineBreak);
const sectionCount = {};
const sectionIndicators = {};
const sectionCodeArray = [];
let fileRowCount = 0;
outputFileRows.forEach((row) => {
if (buildSectionByRow(row, sectionCount, sectionIndicators, sectionCodeArray)) {
fileRowCount++;
}
});
let sectionCountStringContents = "";
let count_9900 = 0;
sectionCodeArray.forEach((sectionCode) => {
const row = `|9900|${sectionCode}|${sectionCount[sectionCode]}|`;
if (sectionCode === "9999") {
sectionCountStringContents = sectionCountStringContents.concat(row, "");
} else {
sectionCountStringContents = sectionCountStringContents.concat(row, options.fileLayout.lineBreak);
}
count_9900++;
fileRowCount++;
});
for (const section in sectionIndicators) {
options.outputFileContents = options.outputFileContents.replace(
SpedFileConstants.BRR_REPLACE_INDICATOR_SECTION + section,
sectionIndicators[section]
);
}
sectionCountStringContents = sectionCountStringContents.replace(
SpedFileConstants.BRR_SECTION_COUNT_REPLACE,
count_9900.toString()
);
const regex = new RegExp(SpedFileConstants.BRR_FILE_ROW_COUNT_REPLACE, "g");
options.outputFileContents = options.outputFileContents
.replace("|9900|", sectionCountStringContents)
.replace(SpedFileConstants.BRR_LAYOUT_SECTION_COUNT_REPLACE, (count_9900 + 3).toString())
.replace(regex, fileRowCount.toString());
return {
fileName: options.fileName,
requestFolderId: options.requestFolderId,
outputFileContents: options.outputFileContents
};
}
|
afterSaveOutputFile(context)
|
Updates the Status field on the SPED File record to Completed after the system saves the file in the File Cabinet.
export function afterSaveOutputFile(outputFileId: string | number, requestParams: FileProcessingRequestParams): void {
const fieldValues: RecordInstanceFieldValue[] = [];
if (outputFileId) {
fieldValues.push({
id: SpedFileFields.Status,
value: getSpedStatusByScriptId(SpedFileStatusEnum.Completed)
});
fieldValues.push({
id: SpedFileFields.GenerationDetails,
value: ""
});
fieldValues.push({
id: SpedFileFields.File,
value: outputFileId
});
updateSpedFileRecord(requestParams.requestParams.spedFile, fieldValues);
}
}
|
processSourceFailure(context)
|
Updates the Status field on the SPED File record to Failed and the Generation Details field with the content of the error message.
export function processSourceFailure(context: GetPendingRequestFailureContext): void {
const fieldValues: RecordInstanceFieldValue[] = [];
fieldValues.push({
id: SpedFileFields.Status,
value: getSpedStatusByScriptId(SpedFileStatusEnum.Failed)
});
fieldValues.push({
id: SpedFileFields.GenerationDetails,
value: context.errorMessage
});
updateSpedFileRecord(context.sourceRecordId, fieldValues);
}
|
customizeFieldValue(context)
|
Returns a specific value for a section source column. For example, the value of the IND_PGTO column based on the transaction type.
export function customizeFieldValue(dataRow: any, field: SourceField, requestParams: RequestParams): string {
const transactionType = dataRow?.recordtype || dataRow?.type;
switch (field.sourceFieldName) {
case SpedSourceFieldNameConstants.DT_INI_ESCR:
case SpedSourceFieldNameConstants.DT_INI:
case SpedSourceFieldNameConstants.MES_REFER:
return getStartDateFromRequestParams(requestParams.startDate);
case SpedSourceFieldNameConstants.DT_FIN:
case SpedSourceFieldNameConstants.DT_EX_SOCIAL:
case SpedSourceFieldNameConstants.DT_FIN_ESCR:
return getEndDateFromRequestParams(requestParams.endDate);
case SpedSourceFieldNameConstants.IND_OPER:
return getOperationTypeIndicator(transactionType);
case SpedSourceFieldNameConstants.IND_EMIT:
return getEDocumentIssuerIndicator(transactionType, dataRow.edocumentstatus);
case SpedSourceFieldNameConstants.COD_SIT:
return getEDocumentSituationCode(transactionType, dataRow.edocumentstatus);
case SpedSourceFieldNameConstants.DT_E_S:
return getEntryDate(transactionType, dataRow.trandate, dataRow.custbody_brl_tran_dt_cert_date);
case SpedSourceFieldNameConstants.IND_PGTO:
return getPaymentIndicator(transactionType, dataRow.daysuntilnetdue);
}
return null;
}
|
For more information about the interface functions, see File Processing Plug-in Interface Definition.
General Notices