'use strict'; const JV = require('./jpc_value_define'); const jpc_common_helper = require('./helper/jpc_helper_common'); const JpcData = { createNew() { const JpcDataRst = {}; JpcDataRst.dataSeq = []; JpcDataRst.exDataSeq = []; JpcDataRst.analyzeData = function(rptTpl, dataObj) { const me = this; const private_analyse = function(MASTER_FIELD_STR, DETAIL_FIELD_STR, MASTER_DATA_STR, DETAIL_DATA_STR, dataSeqArr) { // 1. get ID fields const masterIDs = []; if (rptTpl[JV.NODE_FIELD_MAP][MASTER_FIELD_STR]) { for (let i = 0; i < rptTpl[JV.NODE_FIELD_MAP][MASTER_FIELD_STR].length; i++) { const mstFieldObj = rptTpl[JV.NODE_FIELD_MAP][MASTER_FIELD_STR][i]; if (jpc_common_helper.getBoolean(mstFieldObj[JV.PROP_IS_ID])) { masterIDs.push({ idx: i, seq: mstFieldObj[JV.PROP_ID_SEQ] }); } } } const detailIDs = []; if (rptTpl[JV.NODE_FIELD_MAP][DETAIL_FIELD_STR]) { for (let i = 0; i < rptTpl[JV.NODE_FIELD_MAP][DETAIL_FIELD_STR].length; i++) { const dtlFieldObj = rptTpl[JV.NODE_FIELD_MAP][DETAIL_FIELD_STR][i]; if (jpc_common_helper.getBoolean(dtlFieldObj[JV.PROP_IS_ID])) { detailIDs.push({ idx: i, seq: dtlFieldObj[JV.PROP_ID_SEQ] }); } } } // 2. sort the ID fields if (masterIDs.length > 1) { masterIDs.sort(function(a, b) { return 1 * a.seq - 1 * b.seq; }); } if (detailIDs.length > 1) { detailIDs.sort(function(a, b) { return 1 * a.seq - 1 * b.seq; }); } // 3. prepare data sequence if (masterIDs.length > 0) { let mst_dt_len = 0, dtl_dt_len = 0; const mst_fields = []; for (let i = 0; i < masterIDs.length; i++) { mst_fields.push(dataObj[MASTER_DATA_STR][masterIDs[i].idx]); mst_dt_len = dataObj[MASTER_DATA_STR][masterIDs[i].idx].length; } const dtl_fields = []; for (let i = 0; i < detailIDs.length; i++) { dtl_fields.push(dataObj[DETAIL_DATA_STR][detailIDs[i].idx]); dtl_dt_len = dataObj[DETAIL_DATA_STR][detailIDs[i].idx].length; } let sIdx = 0; let isEqual = true; for (let i = 0; i < mst_dt_len; i++) { dataSeqArr.push([]); // then compare the master/detail ID-field value for (let j = sIdx; j < dtl_dt_len; j++) { isEqual = true; for (let k = 0; k < mst_fields.length; k++) { if (!(mst_fields[k][i] === dtl_fields[k][j])) { isEqual = false; break; } } if (isEqual) { dataSeqArr[i].push(j); } else { sIdx = j; // below logic is for the data robustness purpose, to avoid those strange record(detail level) which could not match even one of the master record! if (i < mst_dt_len - 1 && j < dtl_dt_len - 1) { for (let j1 = j; j1 < dtl_dt_len; j1++) { isEqual = true; for (let k = 0; k < mst_fields.length; k++) { if (!(mst_fields[k][i + 1] === dtl_fields[k][j1])) { isEqual = false; break; } } if (isEqual) { sIdx = j1; break; } } } break; } } } } else { // if no master data if (dataObj && dataObj[DETAIL_DATA_STR] && dataObj[DETAIL_DATA_STR].length > 0) { // may be bill type report which may only have discrete fields! const field = dataObj[DETAIL_DATA_STR][0]; dataSeqArr.push([]); for (let i = 0; i < field.length; i++) { dataSeqArr[0].push(i); } } } }; if ((rptTpl) && (dataObj)) { private_analyse(JV.NODE_MASTER_FIELDS, JV.NODE_DETAIL_FIELDS, JV.DATA_MASTER_DATA, JV.DATA_DETAIL_DATA, me.dataSeq); if (rptTpl[JV.NODE_FLOW_INFO_EX]) { private_analyse(JV.NODE_MASTER_FIELDS_EX, JV.NODE_DETAIL_FIELDS_EX, JV.DATA_MASTER_DATA_EX, JV.DATA_DETAIL_DATA_EX, me.exDataSeq); } } }; return JpcDataRst; }, }; module.exports = JpcData;