|  | @@ -33,13 +33,16 @@ class loadGclBaseTree {
 | 
	
		
			
				|  |  |       * @param {String} code - 子项编号
 | 
	
		
			
				|  |  |       * @returns {*}
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    findNode(node, parent) {
 | 
	
		
			
				|  |  | +    findNode(node, parent, check) {
 | 
	
		
			
				|  |  |          parent = parent || this.parent;
 | 
	
		
			
				|  |  |          if (!parent.children) return null;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          for (const child of parent.children) {
 | 
	
		
			
				|  |  |              const checkLeaf = (child.is_leaf && node.is_leaf) || (!child.is_leaf && !node.is_leaf);
 | 
	
		
			
				|  |  | -            if (child.b_code === node.b_code && child.name === node.name && child.unit === node.unit && checkLeaf) return child;
 | 
	
		
			
				|  |  | +            if (child.b_code === node.b_code && child.name === node.name && child.unit === node.unit
 | 
	
		
			
				|  |  | +                && checkLeaf && (!check || check(child, node))) {
 | 
	
		
			
				|  |  | +                return child;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return null;
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -50,11 +53,9 @@ class loadGclBaseTree {
 | 
	
		
			
				|  |  |       * @param {Object} parent - 父项
 | 
	
		
			
				|  |  |       * @returns {*}
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    addNode(source, parent) {
 | 
	
		
			
				|  |  | -        if (source.b_code === '101') console.log('101 parent', parent);
 | 
	
		
			
				|  |  | +    addNode(source, parent, check) {
 | 
	
		
			
				|  |  |          parent = parent ? parent : this.parent;
 | 
	
		
			
				|  |  | -        let node = this.findNode(source, parent);
 | 
	
		
			
				|  |  | -        if (source.b_code === '101') console.log('101 cur', node);
 | 
	
		
			
				|  |  | +        let node = this.findNode(source, parent, check);
 | 
	
		
			
				|  |  |          if (!node) {
 | 
	
		
			
				|  |  |              if (!parent.children) parent.children = [];
 | 
	
		
			
				|  |  |              node = {
 | 
	
	
		
			
				|  | @@ -114,6 +115,7 @@ class updateReviseGclTree extends loadGclBaseTree {
 | 
	
		
			
				|  |  |      constructor (ctx, setting) {
 | 
	
		
			
				|  |  |          super(ctx, setting);
 | 
	
		
			
				|  |  |          this.baseNodes = [];
 | 
	
		
			
				|  |  | +        this.errors = [];
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      loadBase(datas) {
 | 
	
		
			
				|  |  |          datas.sort((x, y) => { return x.level === y.level ? x.order - y.order : x.level - y.level; });
 | 
	
	
		
			
				|  | @@ -151,7 +153,6 @@ class updateReviseGclTree extends loadGclBaseTree {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      gather(source, parent) {
 | 
	
		
			
				|  |  |          const node = this.addNode(source, parent);
 | 
	
		
			
				|  |  | -        if (source.b_code === '207-2-1') console.log('207-2-1', node, source);
 | 
	
		
			
				|  |  |          node.sgfh_qty = this.ctx.helper.add(node.sgfh_qty, source.sgfh_qty);
 | 
	
		
			
				|  |  |          node.qtcl_qty = this.ctx.helper.add(node.qtcl_qty, source.qtcl_qty);
 | 
	
		
			
				|  |  |          node.sjcl_qty = this.ctx.helper.add(node.sjcl_qty, source.sjcl_qty);
 | 
	
	
		
			
				|  | @@ -167,10 +168,13 @@ class updateReviseGclTree extends loadGclBaseTree {
 | 
	
		
			
				|  |  |                  if (bn.children && bn.children.length > 0) continue;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  if (bn.sjcl_qty < bn.org_sjcl_qty || bn.qtcl_qty < bn.org_qtcl_qty || bn.sgfh_qty < bn.org_sgfh_qty) {
 | 
	
		
			
				|  |  | -                    result.errors.push(bn);
 | 
	
		
			
				|  |  | +                    result.errors.push({
 | 
	
		
			
				|  |  | +                        b_code: bn.b_code, name: bn.name, unit: bn.unit,
 | 
	
		
			
				|  |  | +                        sgfh_qty: bn.sgfh_qty, sjcl_qty: bn.sjcl_qty, qtcl_qty: bn.qtcl_qty, qty: bn.quantity, type: 'less',
 | 
	
		
			
				|  |  | +                    });
 | 
	
		
			
				|  |  |                  } else if (bn.sjcl_qty !== bn.org_sjcl_qty || bn.qtcl_qty !== bn.org_qtcl_qty || bn.sgfh_qty !== bn.org_sgfh_qty) {
 | 
	
		
			
				|  |  |                      result.update.push({
 | 
	
		
			
				|  |  | -                        id: bn.id, sgfh_qty: bn.sgfh_qty, sjcl_qty: bn.sjcl_qty, qtcl_qty: bn.qtcl_qty, quantity: bn.quantity,
 | 
	
		
			
				|  |  | +                        id: bn.id, sgfh_qty: bn.sgfh_qty, sjcl_qty: bn.sjcl_qty, qtcl_qty: bn.qtcl_qty, qty: bn.quantity
 | 
	
		
			
				|  |  |                      })
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -187,6 +191,99 @@ class updateReviseGclTree extends loadGclBaseTree {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +class gatherStageGclTree extends loadGclBaseTree {
 | 
	
		
			
				|  |  | +    constructor (ctx, setting) {
 | 
	
		
			
				|  |  | +        super(ctx, setting);
 | 
	
		
			
				|  |  | +        this.baseNodes = [];
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    loadBase(datas) {
 | 
	
		
			
				|  |  | +        datas.sort((x, y) => { return x.level === y.level ? x.order - y.order : x.level - y.level; });
 | 
	
		
			
				|  |  | +        const Index = {};
 | 
	
		
			
				|  |  | +        for (const d of datas) {
 | 
	
		
			
				|  |  | +            const parent = this.parent.ledger_id === d.ledger_pid ? this.parent : Index[d.ledger_pid];
 | 
	
		
			
				|  |  | +            if (!parent) continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (!parent.children) parent.children = [];
 | 
	
		
			
				|  |  | +            const baseNode = {
 | 
	
		
			
				|  |  | +                id: d.id,
 | 
	
		
			
				|  |  | +                ledger_id: d.ledger_id,
 | 
	
		
			
				|  |  | +                ledger_pid: d.ledger_pid,
 | 
	
		
			
				|  |  | +                level: d.level,
 | 
	
		
			
				|  |  | +                is_leaf: d.is_leaf,
 | 
	
		
			
				|  |  | +                full_path: d.full_path,
 | 
	
		
			
				|  |  | +                b_code: d.b_code,
 | 
	
		
			
				|  |  | +                name: d.name,
 | 
	
		
			
				|  |  | +                unit: d.unit,
 | 
	
		
			
				|  |  | +                unit_price: d.unit_price,
 | 
	
		
			
				|  |  | +                org_contract_qty: d.contract_qty || 0,
 | 
	
		
			
				|  |  | +                org_contract_tp: d.contract_tp || 0,
 | 
	
		
			
				|  |  | +                org_order: d.order,
 | 
	
		
			
				|  |  | +                contract_qty: 0,
 | 
	
		
			
				|  |  | +                contract_tp: 0,
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +            parent.children.push(baseNode);
 | 
	
		
			
				|  |  | +            Index[baseNode.ledger_id] = baseNode;
 | 
	
		
			
				|  |  | +            this.baseNodes.push(baseNode);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    _gatherChange(node, source) {
 | 
	
		
			
				|  |  | +        if (!source.change_detail || source.change_detail.length === 0) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (!node.change_detail) node.change_detail = [];
 | 
	
		
			
				|  |  | +        for (const cd of source.change_detail) {
 | 
	
		
			
				|  |  | +            if (!cd.qty) continue;
 | 
	
		
			
				|  |  | +            let ncd = node.change_detail.find(x => { return x.cid === cd.cid; });
 | 
	
		
			
				|  |  | +            if (!ncd) {
 | 
	
		
			
				|  |  | +                ncd = { cid: cd.cid, c_code: cd.c_code };
 | 
	
		
			
				|  |  | +                node.change_detail.push(ncd);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            ncd.qty = this.ctx.helper.add(ncd.qty, cd.qty);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    gather(source, parent) {
 | 
	
		
			
				|  |  | +        parent = parent ? parent : this.parent;
 | 
	
		
			
				|  |  | +        const node = this.addNode(source, parent, function (node, source) {
 | 
	
		
			
				|  |  | +            return (source.is_tp && node.is_tp) || (!source.is_tp && !node.is_tp);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        if (node.is_tp) {
 | 
	
		
			
				|  |  | +            node.contract_tp = this.ctx.helper.add(node.contract_tp, source.contract_tp);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            node.contract_qty = this.ctx.helper.add(node.contract_qty, source.contract_qty);
 | 
	
		
			
				|  |  | +            node.contract_tp = this.ctx.helper.mul(node.unit_price, node.contract_qty, this.ctx.tender.info.decimal.tp);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        this._gatherChange(node, source);
 | 
	
		
			
				|  |  | +        return node;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    getUpdateData() {
 | 
	
		
			
				|  |  | +        const result = {update: [], errors: []};
 | 
	
		
			
				|  |  | +        for (const bn of this.baseNodes) {
 | 
	
		
			
				|  |  | +            if (bn.contract_qty !== bn.org_contract_qty || bn.contract_tp !== bn.org_contract_tp) {
 | 
	
		
			
				|  |  | +                result.update.push({lid: bn.id, contract_qty: bn.contract_qty, contract_tp: bn.contract_tp });
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (bn.change_detail && bn.change_detail.length > 0) {
 | 
	
		
			
				|  |  | +                for (const cd of bn.change_detail) {
 | 
	
		
			
				|  |  | +                    result.errors.push({
 | 
	
		
			
				|  |  | +                        b_code: bn.b_code, name: bn.name, unit: bn.unit,
 | 
	
		
			
				|  |  | +                        c_code: cd.c_code, qty: cd.qty, type: 'qc',
 | 
	
		
			
				|  |  | +                    });
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        for (const i of this.items) {
 | 
	
		
			
				|  |  | +            result.errors.push({ b_code: i.b_code, name: i.name, unit: i.unit, qty: i.contract_qty, type: 'miss' });
 | 
	
		
			
				|  |  | +            if (i.change_detail && i.change_detail.length > 0) {
 | 
	
		
			
				|  |  | +                for (const cd of i.change_detail) {
 | 
	
		
			
				|  |  | +                    result.errors.push({
 | 
	
		
			
				|  |  | +                        b_code: i.b_code, name: i.name, unit: i.unit,
 | 
	
		
			
				|  |  | +                        c_code: cd.c_code, qty: cd.qty, type: 'miss-qc',
 | 
	
		
			
				|  |  | +                    });
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return result;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class sumLoad {
 | 
	
		
			
				|  |  |      constructor (ctx) {
 | 
	
		
			
				|  |  |          this.ctx = ctx;
 | 
	
	
		
			
				|  | @@ -250,6 +347,64 @@ class sumLoad {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return this.loadTree;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    _loadCurStageAndChange(billsData, curStageBills, curStageChange) {
 | 
	
		
			
				|  |  | +        const billsIndex = {};
 | 
	
		
			
				|  |  | +        for (const b of billsData) {
 | 
	
		
			
				|  |  | +            billsIndex[b.id] = b;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        for (const csb of curStageBills) {
 | 
	
		
			
				|  |  | +            const b = billsIndex[csb.lid];
 | 
	
		
			
				|  |  | +            if (!b) continue;
 | 
	
		
			
				|  |  | +            b.contract_qty = csb.contract_qty;
 | 
	
		
			
				|  |  | +            b.contract_tp = csb.contract_tp;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        for (const csc of curStageChange) {
 | 
	
		
			
				|  |  | +            if (!csc.qty) continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            const b = billsIndex[csc.lid];
 | 
	
		
			
				|  |  | +            if (!b) continue;
 | 
	
		
			
				|  |  | +            if (!b.change_detail) b.change_detail = [];
 | 
	
		
			
				|  |  | +            let c = b.change_detail.find(x => { return x.cid === csc.cid });
 | 
	
		
			
				|  |  | +            if (!c) {
 | 
	
		
			
				|  |  | +                c = { cid: csc.cid };
 | 
	
		
			
				|  |  | +                b.change_detail.push(c);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            c.qty = this.ctx.helper.add(c.qty, csc.qty);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    async stageGatherGcl(select, maxId, tenders, defaultData) {
 | 
	
		
			
				|  |  | +        this.loadTree = new gatherStageGclTree(this.ctx, {
 | 
	
		
			
				|  |  | +            parent: select, maxId, type: 'ledger', defaultData,
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        const posterity = await this.ctx.service.ledger.getPosterityByParentId(this.ctx.tender.id, select.ledger_id);
 | 
	
		
			
				|  |  | +        this.loadTree.loadBase(posterity);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for (const tender of tenders) {
 | 
	
		
			
				|  |  | +            const billsData = await this.ctx.service.ledger.getData(tender.tid);
 | 
	
		
			
				|  |  | +            const stage = await this.ctx.service.stage.getDataByCondition({tid: tender.tid, order: tender.stage});
 | 
	
		
			
				|  |  | +            if (!stage) throw '选择的期不存在';
 | 
	
		
			
				|  |  | +            const curStageData = await this.ctx.service.stageBills.getLastestStageData(tender.tid, stage.id);
 | 
	
		
			
				|  |  | +            const curStageChange = await this.ctx.service.stageChangeFinal.getSumLoadFinalData(stage.id);
 | 
	
		
			
				|  |  | +            this._loadCurStageAndChange(billsData, curStageData, curStageChange);
 | 
	
		
			
				|  |  | +            const billsTree = new Ledger.billsTree(this.ctx, {
 | 
	
		
			
				|  |  | +                id: 'ledger_id',
 | 
	
		
			
				|  |  | +                pid: 'ledger_pid',
 | 
	
		
			
				|  |  | +                order: 'order',
 | 
	
		
			
				|  |  | +                level: 'level',
 | 
	
		
			
				|  |  | +                rootId: -1,
 | 
	
		
			
				|  |  | +                keys: ['id', 'tender_id', 'ledger_id'],
 | 
	
		
			
				|  |  | +                stageId: 'id',
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +            billsTree.loadDatas(billsData);
 | 
	
		
			
				|  |  | +            for (const top of billsTree.children) {
 | 
	
		
			
				|  |  | +                if ([1].indexOf(top.node_type) < 0) continue;
 | 
	
		
			
				|  |  | +                this.recusiveLoadGatherGcl(top, null);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return this.loadTree;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  module.exports = sumLoad;
 |