'use strict'; /** * 清单汇总(需使用path_tree.js, lodash.js) * * @author Mai * @date * @version */ const gclGatherModel = (function () { // 需要汇总计算的字段 const ledgerGatherFields = ['quantity', 'total_price', 'deal_qty', 'deal_tp', 'contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'gather_qty', 'gather_tp', 'end_contract_qty', 'end_contract_tp', 'end_qc_qty', 'end_qc_tp', 'end_gather_qty', 'end_gather_tp']; const posGatherFields = ['quantity', 'contract_qty', 'qc_qty', 'gather_qty', 'end_contract_qty', 'end_qc_qty', 'end_gather_qty']; // 初始化 清单树 const gsTreeSetting = { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'tender_id', 'ledger_id'], stageId: 'id', }; gsTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp']; gsTreeSetting.calcFields = ['deal_tp', 'total_price', 'contract_tp', 'qc_tp', 'gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp']; gsTreeSetting.calcFun = function (node) { if (node.children && node.children.length === 0) { node.gather_qty = ZhCalc.plus(node.contract_qty, node.qc_qty); node.end_contract_qty = ZhCalc.plus(node.pre_contract_qty, node.contract_qty); node.end_qc_qty = ZhCalc.plus(node.pre_qc_qty, node.qc_qty); node.end_gather_qty = ZhCalc.plus(node.pre_gather_qty, node.gather_qty); } node.gather_tp = ZhCalc.plus(node.contract_tp, node.qc_tp); node.end_contract_tp = ZhCalc.plus(node.pre_contract_tp, node.contract_tp); node.end_qc_tp = ZhCalc.plus(node.pre_qc_tp, node.qc_tp); node.end_gather_tp = ZhCalc.plus(node.pre_gather_tp, node.gather_tp); node.dgn_price = ZhCalc.round(ZhCalc.divide(node.total_price, node.dgn_qty1), 2); }; const gsTree = createNewPathTree('stage', gsTreeSetting); // 初始化 部位明细 const posSetting = { id: 'id', ledgerId: 'lid', updateFields: ['contract_qty', 'qc_qty'], }; posSetting.calcFun = function (pos) { pos.gather_qty = ZhCalc.plus(pos.contract_qty, pos.qc_qty); }; const gsPos = new StagePosData(posSetting); const gclList = [], leafXmjs = []; /** * 将所有数据加载至树结构 * * @param ledger - 台账数据 * @param curStage - 当期计量数据 * @param preStage - 截止上期计量数据 * @param bgl - 变更令数据 */ function loadLedgerData (ledger, curStage, preStage, bgl) { // 加载树结构数据 gsTree.loadDatas(ledger); // 加载本期计量数据 if (curStage) { gsTree.loadCurStageData(curStage); } // todo 加载截止上期计量数据 // todo 加载变更令数据 // 根据设置 计算 台账树结构 treeCalc.calculateAll(gsTree); } function loadPosData(pos, curPos, prePos) { gsPos.loadDatas(pos); gsPos.loadCurStageData(curPos); gsPos.loadPreStageData(prePos); } function gatherfields(obj, src, fields) { if (obj && src) { for (const f of fields) { obj[f] = ZhCalc.plus(obj[f], src[f]); } } } /** * 新建 清单汇总节点 * @param node - 最底层 工程量清单节点 * @returns {{b_code: *|string[], name, unit, unit_price: *|string[], leafXmjs: Array}} */ function newGclNode(node) { const gcl = { b_code: node.b_code, name: node.name, unit: node.unit, unit_price: node.unit_price, leafXmjs: [], }; gclList.push(gcl); return gcl; } /** * 获取清单汇总节点 * * @param node - 最底层清单节点 * @returns {*} */ function getGclNode(node) { const gcl = gclList.find(function (g) { return g.b_code === node.b_code && g.name === node.name && g.unit === node.unit && checkZero(g.unit_price - node.unit_price); }); if (gcl) { return gcl } else { return newGclNode(node); } } /** * 检查 text 是否是Peg * e.g. K123+000(true) Kab+123(false) K123.234+234(false) K12+324.234(true) * * @param text * @returns {*} * @constructor */ function CheckPeg(text) { const pegReg = /[kK][0-9][++][0-9]{3}/; return pegReg.test(text); } /** * 获取 桩号节点 * @param node - 检索起始节点 * @returns {*} */ function getPegNode (node) { if (node) { if (CheckPeg(node.name)) { return node; } else { const parent = gsTree.getParent(node); return parent ? getPegNode(parent) : null; } } } /** * 获取节点的第N层父节点 * * @param node - 节点(检索起点) * @param level - 第N层 * @returns {*} */ function getNodeByLevel(node, level) { let cur = node; while (cur && cur.level > level) { cur = gsTree.getParent(cur); } return cur; } /** * 获取 单位工程 * * @param xmj - 计量单元(最底层项目节) * @returns {string} */ function getDwgc(xmj) { const node = getNodeByLevel(xmj, 2); return node ? node.name : ''; } /** * 获取 分部工程 * * @param peg - 桩号节点 * @param xmj - 计量单元(最底层项目节) * @returns {string} */ function getFbgc(peg, xmj) { if (peg && peg.id !== xmj.id) { const node = getNodeByLevel(xmj, peg.level + 1); return node ? node.name : ''; } else { const node = getNodeByLevel(xmj, 3); return node ? node.name : ''; } } /** * 获取 分项工程 * * @param peg - 桩号节点 * @param xmj - 计量单元(最底层项目节) * @returns {string} */ function getFxgc(peg, xmj) { if (!peg) { const node = getNodeByLevel(xmj, 4); return node ? node.name : ''; } else if (peg.id === xmj.id) { if (xmj.level > 4) { let value = ''; for (let level = 4; level < xmj.level; level++) { const node = getNodeByLevel(xmj, level); value = value === '' ? node.name : node.name + '-' + value; } return value; } else { return ''; } } else { if (peg.level - 2 > xmj.level) { let value = ''; for (let level = peg.level + 2; level < xmj.level; level++) { const node = getNodeByLevel(xmj, level); value = value === '' ? node.name : node.name + '-' + value; } return value; } else { return ''; } } } /** * 新建 最底层项目节 缓存数据 * @param leafXmj * @returns {{id, code: *|string[], jldy, fbgc: string, fxgc: string, dwgc: string, bwmx: string, drawing_code: string}} */ function newCacheLeafXmj(leafXmj) { const peg = getPegNode(leafXmj); const cacheLX = { id: leafXmj.id, code: leafXmj.code, jldy: leafXmj.name, fbgc: getFbgc(peg, leafXmj), fxgc: getFxgc(peg, leafXmj), dwgc: getDwgc(leafXmj), drawing_code: leafXmj.drawing_code, }; leafXmjs.push(cacheLX); return cacheLX; } /** * 获取缓存的最底层项目节数据 * * @param leafXmj - 最底层项目节 * @returns {*} */ function getCacheLeafXmj(leafXmj) { const cacheLX = leafXmjs.find(function (lx) { return lx.id === leafXmj.id; }); if (!cacheLX) { return newCacheLeafXmj(leafXmj); } else { return cacheLX; } } /** * 汇总节点 * @param node - 最底层 工程量清单 节点 * @param leafXmj - 所属 最底层 项目节 */ function loadGatherGclNode(node, leafXmj) { const gcl = getGclNode(node); gatherfields(gcl, node, ledgerGatherFields); const cacheLeafXmj = getCacheLeafXmj(leafXmj); const posRange = gsPos.getLedgerPos(node.id); const detail = posRange && posRange.length > 0 ? posRange : [node]; for (const d of detail) { const dx = _.assign({}, cacheLeafXmj); gatherfields(dx, d, posGatherFields); dx.gcl_id = node.id; if (d.name !== node.name) { dx.bwmx = d.name; } if (d.drawing_code) { dx.drawaing_code = d.drawing_code; } gcl.leafXmjs.push(dx); } } /** * (递归)汇总树节点 * @param nodes - 汇总节点列表 * @param leafXmj - 汇总节点所属的底层项目节 */ function recursiveGatherGclData(nodes, leafXmj) { for (const node of nodes) { if (node.b_code) { if (node.children.length > 0) { recursiveGatherGclData(node.children, leafXmj); } else { loadGatherGclNode(node, leafXmj); } } else if (node.children.length > 0) { recursiveGatherGclData(node.children, node); } } } /** * 根据树结构 清单汇总 */ function gatherGclData() { // 清空旧数据 if (gclList.length > 0) { gclList.splice(0, gclList.length - 1); } recursiveGatherGclData(gsTree.children, null); gclList.sort(function (a, b) { function compareCode(code1, code2) { if (numReg.test(code1)) { if (numReg.test(code2)) { return _.toNumber(code1) - _.toNumber(code2); } else { return -1 } } else { if (numReg.test(code2)) { return 1; } else { return code1 === code2 ? 0 : (code1 < code2 ? -1 : 1); } } } const numReg = /^[0-9]+$/; const aCodes = a.b_code.split('-'), bCodes = b.b_code.split('-'); for (let i = 0, iLength = Math.min(aCodes.length, bCodes.length); i < iLength; ++i) { const iCompare = compareCode(aCodes[i], bCodes[i]); if (iCompare !== 0) { return iCompare; } } }); return gclList; } return { loadLedgerData, loadPosData, gatherGclData, }; })();