|
|
@@ -350,7 +350,333 @@ const gclGatherModel = class {
|
|
|
return [this.gclList, this.leafXmjs];
|
|
|
}
|
|
|
};
|
|
|
+const gclCompareGatherModal = class {
|
|
|
+ /**
|
|
|
+ * 构造函数
|
|
|
+ *
|
|
|
+ * @param {Object} ctx - egg 全局变量
|
|
|
+ */
|
|
|
+ constructor(ctx) {
|
|
|
+ this.ctx = ctx;
|
|
|
+ this._ = ctx.helper._;
|
|
|
+ this.defaultSetting = {
|
|
|
+ tree: {
|
|
|
+ id: 'ledger_id',
|
|
|
+ pid: 'ledger_pid',
|
|
|
+ order: 'order',
|
|
|
+ level: 'level',
|
|
|
+ rootId: -1,
|
|
|
+ isLeaf: 'is_leaf',
|
|
|
+ keys: ['id', 'tender_id', 'ledger_id'],
|
|
|
+ stageId: 'id',
|
|
|
+ },
|
|
|
+ pos: { id: 'id', ledgerId: 'lid' },
|
|
|
+ billsFields: ['quantity', 'total_price'],
|
|
|
+ posFields: ['quantity'],
|
|
|
+ chapterFields: ['total_price'],
|
|
|
+ };
|
|
|
+ this.leafXmjs = [];
|
|
|
+ this.gsTree = null;
|
|
|
+ this.gsPos = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ _getCalcChapter(chapter, option) {
|
|
|
+ this.gclChapter = [];
|
|
|
+ this.otherChapter = [];
|
|
|
+ this.gclChapterFilter = [];
|
|
|
+
|
|
|
+ let serialNo = 1;
|
|
|
+ for (const c of chapter) {
|
|
|
+ const cc = { code: c.code, name: c.name, cType: 1 };
|
|
|
+ cc.serialNo = serialNo++;
|
|
|
+ cc.filter = '^[^0-9]*([0-9]{0,2}-)?' + c.code.substr(0, c.code.length - 2) + '[0-9]{2}(-|$)';
|
|
|
+ this.gclChapter.push(cc);
|
|
|
+ }
|
|
|
+ this.gclChapter.push({ name: '未计入章节清单合计', cType: 21, serialNo: serialNo+1 });
|
|
|
+
|
|
|
+ this.otherChapter.hj = { name: '合计(C=A+B+Z)', cType: 41, serialNo: serialNo+5, deal_bills_tp: option.zlj.deal_bills_tp };
|
|
|
+ this.gclChapterFilter.push({node_type: option.jrg.value});
|
|
|
+ this.gclChapterFilter.push({field: 'name', part: option.jrg.text});
|
|
|
+ const zlChapter = {
|
|
|
+ name: '暂列金额(Z)', cType: 32, serialNo: serialNo+4,
|
|
|
+ deal_bills_tp: option.zlj.deal_bills_tp, match: [], matchPath: []
|
|
|
+ };
|
|
|
+ zlChapter.match.push({node_type: option.zlj.value});
|
|
|
+ zlChapter.match.push({field: 'name', part: option.zlj.text});
|
|
|
+ this.otherChapter.zlj = zlChapter;
|
|
|
+
|
|
|
+ this.otherChapter.qd = { name: '清单小计(A)', cType: 11, serialNo: serialNo+2 };
|
|
|
+ this.otherChapter.fqd = { name: '非清单项费用(B)', cType: 31, serialNo: serialNo+3 };
|
|
|
+ }
|
|
|
+ init (chapter, option) {
|
|
|
+ this.gclList = [];
|
|
|
+ this._getCalcChapter(chapter, option);
|
|
|
+ }
|
|
|
+
|
|
|
+ newGclNode(node) {
|
|
|
+ const gcl = {
|
|
|
+ b_code: node.b_code,
|
|
|
+ name: node.name,
|
|
|
+ unit: node.unit,
|
|
|
+ unit_price: node.unit_price,
|
|
|
+ leafXmjs: [],
|
|
|
+ };
|
|
|
+ this.gclList.push(gcl);
|
|
|
+ return gcl;
|
|
|
+ }
|
|
|
+ getGclNode(node) {
|
|
|
+ const gcl = this.gclList.find(function (g) {
|
|
|
+ return g.b_code === node.b_code &&
|
|
|
+ (g.name || node.name ? g.name === node.name : true) &&
|
|
|
+ (g.unit || node.unit ? g.unit === node.unit : true) &&
|
|
|
+ checkZero(this.ctx.helper.sub(g.unit_price, node.unit_price));
|
|
|
+ });
|
|
|
+ if (gcl) {
|
|
|
+ return gcl
|
|
|
+ } else {
|
|
|
+ return this.newGclNode(node);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ gatherfields(obj, src, fields, prefix = '') {
|
|
|
+ if (obj && src) {
|
|
|
+ for (const f of fields) {
|
|
|
+ obj[prefix + f] = this.ctx.helper.add(obj[prefix + f], src[f]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ CheckPeg(text) {
|
|
|
+ const pegReg = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
|
|
|
+ return pegReg.test(text);
|
|
|
+ }
|
|
|
+ getPegNode (node) {
|
|
|
+ if (node) {
|
|
|
+ if (this.CheckPeg(node.name)) {
|
|
|
+ return node;
|
|
|
+ } else {
|
|
|
+ const parent = this.gsTree.getParent(node);
|
|
|
+ return parent ? this.getPegNode(parent) : null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ getPegNode (node) {
|
|
|
+ if (node) {
|
|
|
+ if (this.CheckPeg(node.name)) {
|
|
|
+ return node;
|
|
|
+ } else {
|
|
|
+ const parent = this.gsTree.getParent(node);
|
|
|
+ return parent ? this.getPegNode(parent) : null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ getNodeByLevel(node, level) {
|
|
|
+ let cur = node;
|
|
|
+ while (cur && cur.level > level) {
|
|
|
+ cur = this.gsTree.getParent(cur);
|
|
|
+ }
|
|
|
+ return cur;
|
|
|
+ }
|
|
|
+ getDwgc(peg, xmj) {
|
|
|
+ if (peg) {
|
|
|
+ return peg.name;
|
|
|
+ } else {
|
|
|
+ const node = this.getNodeByLevel(xmj, 2);
|
|
|
+ return node ? node.name : '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ getFbgc(peg, xmj) {
|
|
|
+ if (peg && peg.id !== xmj.id) {
|
|
|
+ const node = this.getNodeByLevel(xmj, peg.level + 1);
|
|
|
+ return node ? node.name : '';
|
|
|
+ } else {
|
|
|
+ const node = this.getNodeByLevel(xmj, 3);
|
|
|
+ return node ? node.name : '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ getFxgc(peg, xmj) {
|
|
|
+ if (!peg) {
|
|
|
+ const node = this.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 = this.getNodeByLevel(xmj, level);
|
|
|
+ value = value === '' ? node.name : value + mergeChar + node.name;
|
|
|
+ }
|
|
|
+ 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 = this.getNodeByLevel(xmj, level);
|
|
|
+ value = value === '' ? node.name : value + mergeChar + node.name;
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ } else {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ newCacheLeafXmj(leafXmj) {
|
|
|
+ const peg = this.getPegNode(leafXmj);
|
|
|
+ const cacheLX = {
|
|
|
+ id: leafXmj.id,
|
|
|
+ code: leafXmj.code,
|
|
|
+ jldy: leafXmj.name,
|
|
|
+ fbgc: this.getFbgc(peg, leafXmj),
|
|
|
+ fxgc: this.getFxgc(peg, leafXmj),
|
|
|
+ dwgc: this.getDwgc(peg, leafXmj),
|
|
|
+ drawing_code: leafXmj.drawing_code,
|
|
|
+ };
|
|
|
+ this.leafXmjs.push(cacheLX);
|
|
|
+ return cacheLX;
|
|
|
+ }
|
|
|
+ getCacheLeafXmj(leafXmj) {
|
|
|
+ const cacheLX = this.leafXmjs.find(function (lx) {
|
|
|
+ return lx.id === leafXmj.id;
|
|
|
+ });
|
|
|
+ if (!cacheLX) {
|
|
|
+ return this.newCacheLeafXmj(leafXmj);
|
|
|
+ } else {
|
|
|
+ return cacheLX;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ loadGatherGclNode(node, leafXmj, gsPos) {
|
|
|
+ const gcl = this.getGclNode(node);
|
|
|
+ this.gatherfields(gcl, node, this.ledgerSetting.billsFields, this.ledgerSetting.prefix);
|
|
|
+ const cacheLeafXmj = this.getCacheLeafXmj(leafXmj);
|
|
|
+ const posRange = gsPos.getLedgerPos(node.id);
|
|
|
+ const detail = posRange && posRange.length > 0 ? posRange : [node];
|
|
|
+ for (const d of detail) {
|
|
|
+ const lx = gcl.leafXmjs.find(x => {return x.id === leafXmj.id && (x.mx_id === d.id || x.gcl_id === d.id)});
|
|
|
+ if (lx) {
|
|
|
+ this.gatherfields(lx, d, this.ledgerSetting.posFields, this.ledgerSetting.prefix);
|
|
|
+ } else {
|
|
|
+ const dx = this._.assign({}, cacheLeafXmj);
|
|
|
+ this.gatherfields(dx, d, this.ledgerSetting.posFields, this.ledgerSetting.prefix);
|
|
|
+ dx.gcl_id = node.id;
|
|
|
+ if (d.name !== node.name) {
|
|
|
+ dx.bwmx = d.name;
|
|
|
+ dx.mx_id = d.id;
|
|
|
+ }
|
|
|
+ if (d.drawing_code) {
|
|
|
+ dx.drawing_code = d.drawing_code;
|
|
|
+ }
|
|
|
+ gcl.leafXmjs.push(dx);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ recursiveGatherGclData(nodes, leafXmj, gsPos) {
|
|
|
+ for (const node of nodes) {
|
|
|
+ if (node.b_code) {
|
|
|
+ if (node.children.length > 0) {
|
|
|
+ this.recursiveGatherGclData(node.children, leafXmj, gsPos);
|
|
|
+ } else {
|
|
|
+ this.loadGatherGclNode(node, leafXmj, gsPos);
|
|
|
+ }
|
|
|
+ } else if (node.children.length > 0) {
|
|
|
+ this.recursiveGatherGclData(node.children, node, gsPos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _getGclChapter(chapter, data) {
|
|
|
+ for (const c of chapter) {
|
|
|
+ if (c.filter) {
|
|
|
+ const reg = new RegExp(c.filter);
|
|
|
+ if (reg.test(data.b_code)) {
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _checkFilter(d, filter) {
|
|
|
+ for (const f of filter) {
|
|
|
+ if (f.node_type && f.node_type === d.node_type) return true;
|
|
|
+ if (f.field) {
|
|
|
+ if (f.part && d[f.field] && d[f.field].indexOf(f.part) >= 0) return true;
|
|
|
+ if (f.all && d[f.all] && d[f.all] === f.all) return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ _gatherChapter() {
|
|
|
+ const chapterFilterPath = [];
|
|
|
+ const checkFilterPath = function (data, filterPath) {
|
|
|
+ for (const fp of filterPath) {
|
|
|
+ if (data.full_path.indexOf(fp + '-') === 0 || data.full_path === fp) return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+
|
|
|
+ for (const d of this.gsTree.nodes) {
|
|
|
+ if (this._checkFilter(d, this.gclChapterFilter)) chapterFilterPath.push(d.full_path);
|
|
|
+ if (this._checkFilter(d, this.otherChapter.zlj.match)) this.otherChapter.zlj.matchPath.push(d.full_path);
|
|
|
+ if (d.children && d.children.length > 0) continue;
|
|
|
+
|
|
|
+ if (checkFilterPath(d, this.otherChapter.zlj.matchPath)) {
|
|
|
+ this.gatherfields(this.otherChapter.zlj, d, this.ledgerSetting.chapterFields, this.ledgerSetting.prefix);
|
|
|
+ this.gatherfields(this.otherChapter.hj, d, this.ledgerSetting.chapterFields, this.ledgerSetting.prefix);
|
|
|
+ } else {
|
|
|
+ this.gatherfields(this.otherChapter.hj, d, this.ledgerSetting.chapterFields, this.ledgerSetting.prefix);
|
|
|
+ if (d.b_code) {
|
|
|
+ this.gatherfields(this.otherChapter.qd, d, this.ledgerSetting.chapterFields, this.ledgerSetting.prefix);
|
|
|
+ }
|
|
|
+ if (!d.b_code || d.b_code === '') {
|
|
|
+ this.gatherfields(this.otherChapter.fqd, d, this.ledgerSetting.chapterFields, this.ledgerSetting.prefix);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (d.b_code) {
|
|
|
+ const c = checkFilterPath(d, chapterFilterPath)
|
|
|
+ ? this.gclChapter.find(x => { return x.cType === 21})
|
|
|
+ : this._getGclChapter(this.gclChapter, d);
|
|
|
+ this.gatherfields(c, d, this.ledgerSetting.chapterFields, this.ledgerSetting.prefix);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ gatherLedgerData (bills, pos, setting) {
|
|
|
+ this.ledgerSetting = this._.assign(setting, this.defaultSetting);
|
|
|
+ try {
|
|
|
+ if (this.leafXmjs.length > 0) this.leafXmjs.length = 0;
|
|
|
+ this.gsTree = new Ledger.billsTree(this.ctx, this.ledgerSetting.tree);
|
|
|
+ this.gsTree.loadDatas(bills);
|
|
|
+ this.gsPos = new Ledger.pos(this.ledgerSetting.pos);
|
|
|
+ this.gsPos.loadDatas(pos);
|
|
|
+ this.recursiveGatherGclData(this.gsTree.children, null, this.gsPos);
|
|
|
+ this._gatherChapter();
|
|
|
+ } catch(err) {
|
|
|
+ this.ctx.log(err);
|
|
|
+ }
|
|
|
+ this.ledgerSetting = null;
|
|
|
+ }
|
|
|
+ gatherReviseLedgerData(bills, pos, setting, price, decimal) {
|
|
|
+ this.ledgerSetting = this._.assign(setting, this.defaultSetting);
|
|
|
+ try {
|
|
|
+ if (this.leafXmjs.length > 0) this.leafXmjs.length = 0;
|
|
|
+ this.gsTree = new Ledger.reviseTree(this.ctx, this.ledgerSetting.tree);
|
|
|
+ this.gsTree.loadRevisePrice(price, decimal);
|
|
|
+ this.gsTree.loadDatas(bills);
|
|
|
+ this.gsPos = new Ledger.pos(this.ledgerSetting.pos);
|
|
|
+ this.gsPos.loadDatas(pos);
|
|
|
+ this.recursiveGatherGclData(this.gsTree.children, null, this.gsPos);
|
|
|
+ this._gatherChapter();
|
|
|
+ } catch(err) {
|
|
|
+ this.ctx.log(err);
|
|
|
+ }
|
|
|
+ this.ledgerSetting = null;
|
|
|
+ }
|
|
|
+ chapterData () {
|
|
|
+ return this.gclChapter.concat([this.otherChapter.qd, this.otherChapter.fqd, this.otherChapter.zlj, this.otherChapter.hj]);
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
module.exports = {
|
|
|
gclGather: gclGatherModel,
|
|
|
+ gclCompareGather: gclCompareGatherModal,
|
|
|
};
|