|
@@ -2159,7 +2159,7 @@ class CalcProgram {
|
|
|
// 计算零散的、混杂的树节点:清单、定额混合等(如:用到某一计算程序的定额和清单)。
|
|
|
// 计算多条零散的定额,并计算他们所属的清单、父清单、引用清单。如:批量替换工料机后受影响的定额。
|
|
|
// 计算多条零散的清单,并计算他们的父清单、引用清单。如:花选删除树结点(如花选清单、定额等,不区分树结点类型)。
|
|
|
- calcNodesAndSave(nodes, callback, tender){
|
|
|
+ calcNodes(nodes, tender){
|
|
|
let me = this, rationNodes = [], billNodes = [], leafBills = [], allChangedNodes = [];
|
|
|
for (let node of nodes) {
|
|
|
if (node.sourceType == ModuleNames.ration)
|
|
@@ -2184,7 +2184,13 @@ class CalcProgram {
|
|
|
};
|
|
|
|
|
|
me.calcFormulaNodes(allChangedNodes, tender);
|
|
|
- me.saveNodes(allChangedNodes, callback);
|
|
|
+ return allChangedNodes;
|
|
|
+ };
|
|
|
+
|
|
|
+ calcNodesAndSave(nodes, callback, tender){
|
|
|
+ let me = this;
|
|
|
+ let chgNodes = me.calcNodes(nodes, tender);
|
|
|
+ me.saveNodes(chgNodes, callback);
|
|
|
};
|
|
|
|
|
|
// 计算全部公式项。 (changedArr:将通过本方法后发生改变的节点存入changedArr中)
|
|
@@ -2504,125 +2510,125 @@ class CalcProgram {
|
|
|
|
|
|
// 按指定的比例获取可接受的差值:如目标金额的万分之一。
|
|
|
function getPropV(node){
|
|
|
- let v = parseFloat((node.data.targetTotalFee * diffProp).toFixed(0)); // node.data.feesIndex.common.totalFee
|
|
|
- return Math.max(v, MaxDiffValue);
|
|
|
+ let v = parseFloat((node.data.targetTotalFee * diffProp).toFixed(0)); // node.data.feesIndex.common.totalFee
|
|
|
+ return Math.max(v, MaxDiffValue);
|
|
|
}
|
|
|
|
|
|
// 取根结点的:调后金额跟目标金额差值,看还有多少误差需要处理。
|
|
|
function getRootDiff() {
|
|
|
- let root = tender_obj.tenderTree.roots[0];
|
|
|
- return (root.data.feesIndex.common.tenderTotalFee - root.data.targetTotalFee).toDecimal(3);
|
|
|
+ let root = tender_obj.tenderTree.roots[0];
|
|
|
+ return (root.data.feesIndex.common.tenderTotalFee - root.data.targetTotalFee).toDecimal(3);
|
|
|
}
|
|
|
|
|
|
// 生成每单位差值的定额结点列表。
|
|
|
function getNodeDiffs() {
|
|
|
- let arr = [];
|
|
|
- for (let i = 0; i < tender_obj.tenderTree.items.length; i++) {
|
|
|
- let node = tender_obj.tenderTree.items[i];
|
|
|
- // 量价还是要参与,因为它贡献了金额,如果它的金额比重很大,它退出了,会导致其它结点过调。
|
|
|
- // if (calcTools.isRationCategory(node) && (!calcTools.isVP_or_GLJR(node))){
|
|
|
- if (calcTools.isRationCategory(node)){
|
|
|
- let coe = calcTools.getCoe(node, tender);
|
|
|
- if (coe!= 0) {
|
|
|
- let diff = Math.abs(node.data.feesIndex.common.tenderTotalFee - node.data.feesIndex.common.totalFee);
|
|
|
- node.data.tender_diffValuePerCoe = (diff * G_DIGIT / coe).toDecimal(decimalObj.process);
|
|
|
- node.data.tender_rowNo = i + 1; // node在UI上显示的行号
|
|
|
- arr.push(node);
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
- arr.sort(function sortArr(a, b) { return a.data.tender_diffValuePerCoe - b.data.tender_diffValuePerCoe});
|
|
|
+ let arr = [];
|
|
|
+ for (let i = 0; i < tender_obj.tenderTree.items.length; i++) {
|
|
|
+ let node = tender_obj.tenderTree.items[i];
|
|
|
+ // 量价还是要参与,因为它贡献了金额,如果它的金额比重很大,它退出了,会导致其它结点过调。
|
|
|
+ // if (calcTools.isRationCategory(node) && (!calcTools.isVP_or_GLJR(node))){
|
|
|
+ if (calcTools.isRationCategory(node)){
|
|
|
+ let coe = calcTools.getCoe(node, tender);
|
|
|
+ if (coe!= 0) {
|
|
|
+ let diff = Math.abs(node.data.feesIndex.common.tenderTotalFee - node.data.feesIndex.common.totalFee);
|
|
|
+ node.data.tender_diffValuePerCoe = (diff * G_DIGIT / coe).toDecimal(decimalObj.process);
|
|
|
+ node.data.tender_rowNo = i + 1; // node在UI上显示的行号
|
|
|
+ arr.push(node);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ arr.sort(function sortArr(a, b) { return a.data.tender_diffValuePerCoe - b.data.tender_diffValuePerCoe});
|
|
|
|
|
|
- if (isTest){
|
|
|
- let arr2 = [];
|
|
|
- for (let i = 0; i < arr.length; i++) {
|
|
|
- arr2.push({row: arr[i].data.tender_rowNo, code: arr[i].data.code + ' ' + arr[i].data.name, diff: arr[i].data.tender_diffValuePerCoe});
|
|
|
+ if (isTest){
|
|
|
+ let arr2 = [];
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ arr2.push({row: arr[i].data.tender_rowNo, code: arr[i].data.code + ' ' + arr[i].data.name, diff: arr[i].data.tender_diffValuePerCoe});
|
|
|
+ }
|
|
|
+ console.log(arr2);
|
|
|
}
|
|
|
- console.log(arr2);
|
|
|
- }
|
|
|
|
|
|
- return arr;
|
|
|
+ return arr;
|
|
|
}
|
|
|
|
|
|
// 每单位差值的定额结点列表中,取离给定值最近的定额结点。
|
|
|
function getCloseNode(arr, value) {
|
|
|
- let index = 0;
|
|
|
- let d_value = Number.MAX_VALUE;
|
|
|
- for (let i = 0; i < arr.length; i++) {
|
|
|
- let new_d_value = Math.abs(arr[i].data.tender_diffValuePerCoe - value);
|
|
|
- if (new_d_value <= d_value) {
|
|
|
- if (new_d_value === d_value && arr[i].data.tender_diffValuePerCoe < arr[index].data.tender_diffValuePerCoe) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- index = i;
|
|
|
- d_value = new_d_value;
|
|
|
+ let index = 0;
|
|
|
+ let d_value = Number.MAX_VALUE;
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ let new_d_value = Math.abs(arr[i].data.tender_diffValuePerCoe - value);
|
|
|
+ if (new_d_value <= d_value) {
|
|
|
+ if (new_d_value === d_value && arr[i].data.tender_diffValuePerCoe < arr[index].data.tender_diffValuePerCoe) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ index = i;
|
|
|
+ d_value = new_d_value;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- return {idx: index, node: arr[index]}
|
|
|
+ return {idx: index, node: arr[index]}
|
|
|
}
|
|
|
|
|
|
// 逼近(单轮)。arr 参考取值列表。返回{type, node, nodeIdx}。
|
|
|
// type:1正常,2无结点,3结点过调。node:结点。nodeIdx:结点在列表中的索引位置。node.data.tender_rowNo 在UI上的行号。
|
|
|
function approach(arr){
|
|
|
- let v = getRootDiff();
|
|
|
- let obj = getCloseNode(arr, Math.abs(v)); // {idx, node} 极端:{0, undefind}
|
|
|
- let closeNode = obj.node;
|
|
|
- if (!closeNode)
|
|
|
- return {type: 2, node: undefined, nodeIdx: -1}; // arr 被清空了
|
|
|
-
|
|
|
- let d = (v > 0) ? -G_DIGIT : G_DIGIT;
|
|
|
- let coe = calcTools.getCoe(closeNode, tender);
|
|
|
- if ((coe + d) < 0)
|
|
|
- return {type: 3, node: obj.node, nodeIdx: obj.idx}; // 再调的话,系数就变负数了,过调
|
|
|
-
|
|
|
- if (tender == tenderTypes.ttReverseRation){
|
|
|
- closeNode.data.tender_previousCoe = closeNode.data.rationQuantityCoe; // tender_previousCoe: 上一次的调整系数,用于撤回
|
|
|
- closeNode.data.rationQuantityCoe = (closeNode.data.rationQuantityCoe + d).toDecimal(decimalObj.process);
|
|
|
- }
|
|
|
- else if (tender == tenderTypes.ttReverseGLJ){
|
|
|
- if (calcTools.isVP_or_GLJR(closeNode)){
|
|
|
- closeNode.data.tender_previousCoe = closeNode.data.rationQuantityCoe;
|
|
|
- closeNode.data.rationQuantityCoe = (closeNode.data.rationQuantityCoe + d).toDecimal(decimalObj.process);
|
|
|
+ let v = getRootDiff();
|
|
|
+ let obj = getCloseNode(arr, Math.abs(v)); // {idx, node} 极端:{0, undefind}
|
|
|
+ let closeNode = obj.node;
|
|
|
+ if (!closeNode)
|
|
|
+ return {type: 2, node: undefined, nodeIdx: -1}; // arr 被清空了
|
|
|
+
|
|
|
+ let d = (v > 0) ? -G_DIGIT : G_DIGIT;
|
|
|
+ let coe = calcTools.getCoe(closeNode, tender);
|
|
|
+ if ((coe + d) < 0)
|
|
|
+ return {type: 3, node: obj.node, nodeIdx: obj.idx}; // 再调的话,系数就变负数了,过调
|
|
|
+
|
|
|
+ if (tender == tenderTypes.ttReverseRation){
|
|
|
+ closeNode.data.tender_previousCoe = closeNode.data.rationQuantityCoe; // tender_previousCoe: 上一次的调整系数,用于撤回
|
|
|
+ closeNode.data.rationQuantityCoe = (closeNode.data.rationQuantityCoe + d).toDecimal(decimalObj.process);
|
|
|
+ }
|
|
|
+ else if (tender == tenderTypes.ttReverseGLJ){
|
|
|
+ if (calcTools.isVP_or_GLJR(closeNode)){
|
|
|
+ closeNode.data.tender_previousCoe = closeNode.data.rationQuantityCoe;
|
|
|
+ closeNode.data.rationQuantityCoe = (closeNode.data.rationQuantityCoe + d).toDecimal(decimalObj.process);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ closeNode.data.tender_previousCoe = closeNode.data.quantityCoe.labour;
|
|
|
+ closeNode.data.quantityCoe.labour = (closeNode.data.quantityCoe.labour + d).toDecimal(decimalObj.process)
|
|
|
+ closeNode.data.quantityCoe.material = (closeNode.data.quantityCoe.material + d).toDecimal(decimalObj.process)
|
|
|
+ closeNode.data.quantityCoe.machine = (closeNode.data.quantityCoe.machine + d).toDecimal(decimalObj.process)
|
|
|
+ closeNode.data.quantityCoe.main = (closeNode.data.quantityCoe.main + d).toDecimal(decimalObj.process)
|
|
|
+ closeNode.data.quantityCoe.equipment = (closeNode.data.quantityCoe.equipment + d).toDecimal(decimalObj.process)
|
|
|
+ };
|
|
|
}
|
|
|
- else {
|
|
|
- closeNode.data.tender_previousCoe = closeNode.data.quantityCoe.labour;
|
|
|
- closeNode.data.quantityCoe.labour = (closeNode.data.quantityCoe.labour + d).toDecimal(decimalObj.process)
|
|
|
- closeNode.data.quantityCoe.material = (closeNode.data.quantityCoe.material + d).toDecimal(decimalObj.process)
|
|
|
- closeNode.data.quantityCoe.machine = (closeNode.data.quantityCoe.machine + d).toDecimal(decimalObj.process)
|
|
|
- closeNode.data.quantityCoe.main = (closeNode.data.quantityCoe.main + d).toDecimal(decimalObj.process)
|
|
|
- closeNode.data.quantityCoe.equipment = (closeNode.data.quantityCoe.equipment + d).toDecimal(decimalObj.process)
|
|
|
- };
|
|
|
- }
|
|
|
|
|
|
- me.calculate(closeNode, true, true, tenderTypes.ttCalc);
|
|
|
- return {type: 1, node: obj.node, nodeIdx: obj.idx};
|
|
|
+ me.calculate(closeNode, true, true, tenderTypes.ttCalc);
|
|
|
+ return {type: 1, node: obj.node, nodeIdx: obj.idx};
|
|
|
}
|
|
|
|
|
|
// 撤消最后一轮逼近(调过头了,回退一步)
|
|
|
function undoLastApproach(obj){
|
|
|
- let closeNode = obj.node;
|
|
|
- let coe = closeNode.data.tender_previousCoe;
|
|
|
- if (tender == tenderTypes.ttReverseRation){
|
|
|
- closeNode.data.rationQuantityCoe = coe
|
|
|
- } else if (tender == tenderTypes.ttReverseGLJ){
|
|
|
- if (calcTools.isVP_or_GLJR(closeNode)){
|
|
|
- closeNode.data.rationQuantityCoe = coe
|
|
|
+ let closeNode = obj.node;
|
|
|
+ let coe = closeNode.data.tender_previousCoe;
|
|
|
+ if (tender == tenderTypes.ttReverseRation){
|
|
|
+ closeNode.data.rationQuantityCoe = coe
|
|
|
+ } else if (tender == tenderTypes.ttReverseGLJ){
|
|
|
+ if (calcTools.isVP_or_GLJR(closeNode)){
|
|
|
+ closeNode.data.rationQuantityCoe = coe
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ closeNode.data.quantityCoe.labour = coe
|
|
|
+ closeNode.data.quantityCoe.material = coe
|
|
|
+ closeNode.data.quantityCoe.machine = coe
|
|
|
+ closeNode.data.quantityCoe.main = coe
|
|
|
+ closeNode.data.quantityCoe.equipment = coe
|
|
|
+ };
|
|
|
}
|
|
|
- else {
|
|
|
- closeNode.data.quantityCoe.labour = coe
|
|
|
- closeNode.data.quantityCoe.material = coe
|
|
|
- closeNode.data.quantityCoe.machine = coe
|
|
|
- closeNode.data.quantityCoe.main = coe
|
|
|
- closeNode.data.quantityCoe.equipment = coe
|
|
|
- };
|
|
|
- }
|
|
|
|
|
|
- me.calculate(closeNode, true, true, tenderTypes.ttCalc);
|
|
|
- if (isTest) {
|
|
|
- let _sp = ` `; // 保留空格,打印对齐
|
|
|
- let _node = `[行${obj.node.data.tender_rowNo} 索引${obj.nodeIdx}]`;
|
|
|
- console.log(`${_sp} ${_node} 过调,已回退`);
|
|
|
- }
|
|
|
+ me.calculate(closeNode, true, true, tenderTypes.ttCalc);
|
|
|
+ if (isTest) {
|
|
|
+ let _sp = ` `; // 保留空格,打印对齐
|
|
|
+ let _node = `[行${obj.node.data.tender_rowNo} 索引${obj.nodeIdx}]`;
|
|
|
+ console.log(`${_sp} ${_node} 过调,已回退`);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
let root = tender_obj.tenderTree.roots[0];
|