Browse Source

1. 预处理,新增汇总合同支付
2. 预处理,新增合并数据
3. 预处理,调整原有的章级汇总

MaiXinRong 5 years ago
parent
commit
e8764babfd

+ 204 - 10
app/lib/rpt_data_analysis.js

@@ -10,6 +10,38 @@
 
 const math = require('mathjs');
 const standard = require('../const/standard');
+
+// 通用方法
+const rdaUtils = {
+    orderCalc: function (ctx, data, fields) {
+        const orderMatch = new RegExp('o[0-9]+', 'igm');
+        for (const c of data) {
+            if (c.order_calc && c.order_calc !== '') {
+                const matchs = c.order_calc.match(orderMatch);
+                const calcMatch = [];
+                for (const m of matchs) {
+                    const order = m.substring(1, m.length);
+                    const orderData = data.find(function (x) {return (x.order + '') === order});
+                    if (orderData) {
+                        calcMatch.push({match: m, value: orderData})
+                    }
+                }
+                for (const f of fields) {
+                    let expr = c.order_calc;
+                    for (const m of calcMatch) {
+                        expr = expr.replace(m.match, m.value[f] ? m.value[f] : 0);
+                    }
+                    try {
+                        c[f] = ctx.helper.round(math.eval(expr), 6);
+                    } catch(err) {
+                    }
+                }
+            }
+        }
+    }
+};
+
+// 可提供的数据处理方法
 const changeSort = {
     name: '变更令排序',
     hint: '默认的变更令排序,同时对变更令,变更清单进行排序\n' +
@@ -189,6 +221,7 @@ const gatherChapter = {
     },
     customSetting1: {
         count: 7,
+        other: 1,
         gclSum: {
             name: '第100章至700章清单合计',
             order: 1,
@@ -197,7 +230,7 @@ const gatherChapter = {
             {name: '已包含在清单合计中的材料、工程设备、专业工程暂估价', order: 2},
             {name: '清单合计减去材料、工程设备、专业工程暂估价(即8-9=10)', order_calc: 'o1-o2', order: 3},
             {name: '计日工合计', node_type: '计日工', order: 4},
-            {name: '暂列金额(不含计日工总额)(即10×暂列金额比列)', node_type: '暂列金额', order: 5},
+            {name: '暂列金额(不含计日工总额)(即10×暂列金额比列)', order: 5, match: [{node_type: '暂列金额'}, {field: 'name', part: '暂列金额'}, {field: 'name', part: '暂定金额'}]},
             {name: '投标报价、台账价(8+11+12)=13', order_calc: 'o1+o4+o5', order: 6},
         ],
     },
@@ -211,7 +244,11 @@ const gatherChapter = {
             cc.filter = '^' + c.code.substr(0, c.code.length - 2) + '[0-9]{2}-';
             gclChapter.push(cc);
 
-            if (serialNo > options.count) break;
+            if (options.activeFields) {
+                cc.active = cc.serialNo > options.count;
+            } else {
+                if (serialNo > options.count) break;
+            }
         }
 
         if (options.unChapter) {
@@ -234,11 +271,14 @@ const gatherChapter = {
                     order_calc: c.order_calc,
                     cType: 5, order: c.order,
                 };
-                if (c.node_type && c.node_type !== '') {
-                    const nodeType = standard.nodeType.find(function (x) {return x.text === c.node_type});
-                    cc.node_type = nodeType.value;
-                } else {
-                    cc.node_type = -1;
+                if (c.match) {
+                    cc.match = JSON.parse(JSON.stringify(c.match));
+                    for (const m of cc.match) {
+                        if (m.node_type && m.node_type !== '') {
+                            const nodeType = standard.nodeType.find(function (x) {return x.text === m.node_type});
+                            m.node_type = nodeType.value;
+                        }
+                    }
                 }
                 customChapter.push(cc);
             }
@@ -289,6 +329,19 @@ const gatherChapter = {
             }
         }
     },
+    _checkMatch: function (match, d) {
+        for (const m of match) {
+            if (m.node_type) {
+                if (m.node_type === d.node_type) return true;
+            } else if (m.field) {
+                const value = d[m.field];
+                if (m.part) {
+                    if (value.indexOf(m.part) >= 0) return true;
+                }
+            }
+        }
+        return false;
+    },
     fun: function (ctx, data, fieldsKey, options) {
         if (!data.tender_info || !data.tender_info.chapter) return;
         if (!fieldsKey && fieldsKey.length < 0) return;
@@ -316,7 +369,7 @@ const gatherChapter = {
         const filter = [];
         for (const d of sourceData) {
             for (const c of customChapter) {
-                if (c.node_type && c.node_type > 0 && c.node_type === d.node_type) {
+                if (c.match && this._checkMatch(c.match, d)) {
                     gatherData(c, d);
                     filter.push(d.full_path);
                 }
@@ -342,7 +395,16 @@ const gatherChapter = {
         this._orderCalc(ctx, chapter, calcFields);
         chapter.sort(function (a, b) {return a.serialNo - b.serialNo});
 
-        data[fieldsKey[0].table] = chapter;
+        data[fieldsKey[0].table] = chapter.filter(function (x) {
+            if (x.active) {
+                for (const f of options.activeFields) {
+                    if (!ctx.helper.checkZero(x[f])) return true;
+                }
+                return false;
+            } else {
+                return true;
+            }
+        });
     },
 };
 const join = {
@@ -517,6 +579,136 @@ const filter = {
         data[options.table] = result;
     }
 };
+const gatherStagePay = {
+    name: '汇总合同支付数据',
+    intro: '根据付扣款项等,分类汇总合同支付的数据',
+    defaultSetting: {
+        table: 'mem_stage_pay',
+        custom: [
+            {name: '本期完成计量', ptype: 4, order: 1, visible: false},
+            {name: '业主违约罚金', match: '业主违约罚金', order: 2},
+            {name: '迟付款利息', match: '迟付款利息', order: 3},
+            {name: '其他付款', minus: 0, rid: ['业主违约罚金', '迟付款利息'], order: 4},
+            {name: '合计', order: 5, order_calc: 'o1+o2+o3+o4', },
+            {name: '动员预付款', order: 6},
+            {name: '扣动员预付款', match: ['扣动员预付款', '扣回动员预付款', '扣开工预付款', '扣回开工预付款'], order: 7},
+            {name: '扣材料预付款', match: '扣材料预付款', order: 8},
+            {name: '承包人违约罚金', match: '承包人违约罚金', order: 9},
+            {name: '保留金', match: '保留金', order: 10},
+            {name: '税金', match: '税金', order: 11},
+            {name: '质量保证金', match: '质量保证金', order: 12},
+            {name: '其他扣款', minus: 1, rid: ['扣动员预付款', '扣回动员预付款', '扣开工预付款', '扣回开工预付款', '扣材料预付款', '承包人违约罚金', '保留金', '税金', '质量保证金'], order: 13},
+            {name: '扣款合计', minus: 1, rid: [], order: 14},
+            {name: '支付', ptype: 2, order: 15},
+        ]
+    },
+    _gatherFields: function (ctx, d, source, calcFields) {
+        let filterData = source;
+        if (d.ptype) {
+            filterData = filterData.filter(function (x) {
+                return x.ptype === d.ptype;
+            });
+        }
+        if (d.match) {
+            filterData = filterData.filter(function (x) {
+                if (d.match instanceof Array) {
+                    for (const m of d.match) {
+                        if (x.name.indexOf(m) >= 0) return true;
+                    }
+                } else {
+                    return x.name.indexOf(d.match) >= 0;
+                }
+            });
+        }
+        if (!ctx.helper._.isNil(d.minus)) {
+            filterData = filterData.filter(function (x) {
+                return d.minus === 1 ? x.minus : !x.minus;
+            });
+        }
+        if (d.rid) {
+            filterData = filterData.filter(function (x) {
+                for (const r of d.rid) {
+                    if (x.name.indexOf(r) >= 0) return false;
+                }
+                return true;
+            });
+        }
+        for (const fd of filterData) {
+            for (const prop in fd) {
+                if (prop.indexOf('tp') >= 0) {
+                    d[prop] = ctx.helper.add(d[prop], fd[prop]);
+                    if (calcFields.indexOf(prop) === -1) calcFields.push(prop);
+                }
+            }
+        }
+    },
+    fun: function (ctx, data, fields, options) {
+        if (!options || !options.table || !options.custom) return;
+
+        const gatherData = data[options.table];
+        const result = [], calcFields = [];
+        for (const c of options.custom) {
+            const cData = JSON.parse(JSON.stringify(c));
+            if (!cData.order_calc && cData.empty !== 1) {
+                this._gatherFields(ctx, cData, gatherData, calcFields);
+            }
+            result.push(cData);
+        }
+        rdaUtils.orderCalc(ctx, result, calcFields);
+        data[options.table] = result.filter(function (x) {
+            return x.visible === undefined || x.visible;
+        });
+    },
+};
+const union = {
+    name: '合并数据',
+    intro: '类似sql的union,可合并任意数据,合并结果写到"预留扩展数据-合并(mem_union_data)"中',
+    defaultSetting: {
+        union: [
+            {
+                table: 'mem_stage_bills',
+                fields: [
+                    {target: 'str1', source: 'chapter'},
+                    {target: 'str2', source: 'name'},
+                    {target: 'tp1', source: 'total_price'},
+                    {target: 'tp2', source: 'gather_tp'},
+                    {target: 'tp3', source: 'pre_gather_tp'},
+                    {target: 'tp4', source: 'end_gather_tp'},
+                    {target: 'str3', data: '章级合计哟'},
+                ]
+            }, {
+                table: 'mem_stage_pay',
+                fields: [
+                    {target: 'str2', source: 'name'},
+                    {target: 'tp2', source: 'tp'},
+                    {target: 'tp3', source: 'pre_tp'},
+                    {target: 'tp4', source: 'end_tp'},
+                    {target: 'str3', data: '合同支付哟'},
+                ]
+            }
+        ]
+    },
+    fun: function(ctx, data, fields, options) {
+        if (!options || !options.union) return;
+
+        const result = [];
+        for (const u of options.union) {
+            const unionData = data[u.table];
+            for (const d of unionData) {
+                const nd = {};
+                for (const f of u.fields) {
+                    if (f.data) {
+                        nd[f.target] = f.data;
+                    } else if (f.source) {
+                        nd[f.target] = d[f.source];
+                    }
+                }
+                result.push(nd);
+            }
+        }
+        data.mem_union_data = result;
+    }
+};
 
 const analysisObj = {
     changeSort,
@@ -525,7 +717,9 @@ const analysisObj = {
     gatherChapter,
     join,
     getChapterCode,
-    filter
+    filter,
+    union,
+    gatherStagePay,
 };
 const analysisDefine = (function (obj) {
     const result = [];

+ 7 - 0
app/service/report.js

@@ -92,6 +92,10 @@ module.exports = app => {
                             runnableRst.push(service.reportMemory.getStageBillsCompareData(params.tender_id, params.stage_id, memFieldKeys[filter]));
                             runnableKey.push(filter);
                             break;
+                        case 'mem_stage_pay':
+                            runnableRst.push(service.reportMemory.getStagePayData(params.tender_id, params.stage_id, memFieldKeys[filter]));
+                            runnableKey.push(filter);
+                            break;
                         case 'change':
                             runnableRst.push(service.change.getListByStatus(params.tender_id, 3)); // 获取所有审核通过的变更主信息
                             runnableKey.push(filter);
@@ -117,6 +121,9 @@ module.exports = app => {
                     case 'mem_stage_im_tz_bills':
                         rst[filter] = await service.reportMemory.getStageImTzBillsData(params.tender_id, params.stage_id, memFieldKeys[filter]);
                         break;
+                    case 'mem_union_data':
+                        rst[filter] = [];
+                        break;
                     default:
                         break;
                 }

+ 1 - 1
app/service/report_memory.js

@@ -516,7 +516,7 @@ module.exports = app => {
 
             const dealPay = await this.ctx.service.stagePay.getStagePays(this.ctx.stage);
 
-            if (!this.ctx.stage.readOnly && this.ctx.stage.check_calc) {
+            if (!this.ctx.stage.readOnly) {
                 // 计算 本期金额
                 const PayCalculator = require('../lib/pay_calc');
                 const payCalculator = new PayCalculator(this.ctx, this.ctx.stage, this.ctx.tender.info);

+ 49 - 0
test/app/service/report_memory.test.js

@@ -321,4 +321,53 @@ describe('test/app/service/report_memory.test.js', () => {
             yield saveTableDefine(ctx, tableDefine, ctx.app.baseDir + '/mem_stage_pay_define.json');
         }
     });
+    it('test mem_union_data', function* () {
+        const ctx = app.mockContext(mockData);
+
+        const tableDefine = {};
+        tableDefine.Name = '预留扩展数据-合并(mem_union_data)';
+        tableDefine.remark = '';
+        tableDefine.ID = 28;
+        tableDefine.key = 'mem_union_data';
+        tableDefine.items = [];
+        const prefix = '预留扩展数据-合并-';
+
+        addFields(tableDefine, prefix + '字符串1', 'str1', dataType.str);
+        addFields(tableDefine, prefix + '字符串2', 'str2', dataType.str);
+        addFields(tableDefine, prefix + '字符串3', 'str3', dataType.str);
+        addFields(tableDefine, prefix + '字符串4', 'str4', dataType.str);
+        addFields(tableDefine, prefix + '字符串5', 'str5', dataType.str);
+        addFields(tableDefine, prefix + '字符串6', 'str6', dataType.str);
+        addFields(tableDefine, prefix + '字符串7', 'str7', dataType.str);
+        addFields(tableDefine, prefix + '字符串8', 'str8', dataType.str);
+        addFields(tableDefine, prefix + '字符串9', 'str9', dataType.str);
+        addFields(tableDefine, prefix + '字符串10', 'str10', dataType.str);
+        addFields(tableDefine, prefix + '整数1', 'int1', dataType.int);
+        addFields(tableDefine, prefix + '整数2', 'int2', dataType.int);
+        addFields(tableDefine, prefix + '整数3', 'int3', dataType.int);
+        addFields(tableDefine, prefix + '整数4', 'int4', dataType.int);
+        addFields(tableDefine, prefix + '整数5', 'int5', dataType.int);
+        addFields(tableDefine, prefix + '整数6', 'int6', dataType.int);
+        addFields(tableDefine, prefix + '数量1', 'qty1', dataType.currency);
+        addFields(tableDefine, prefix + '数量2', 'qty2', dataType.currency);
+        addFields(tableDefine, prefix + '数量3', 'qty3', dataType.currency);
+        addFields(tableDefine, prefix + '数量4', 'qty4', dataType.currency);
+        addFields(tableDefine, prefix + '数量5', 'qty5', dataType.currency);
+        addFields(tableDefine, prefix + '数量6', 'qty6', dataType.currency);
+        addFields(tableDefine, prefix + '数量7', 'qty7', dataType.currency);
+        addFields(tableDefine, prefix + '数量8', 'qty8', dataType.currency);
+        addFields(tableDefine, prefix + '数量9', 'qty9', dataType.currency);
+        addFields(tableDefine, prefix + '数量10', 'qty10', dataType.currency);
+        addFields(tableDefine, prefix + '金额1', 'tp1', dataType.currency);
+        addFields(tableDefine, prefix + '金额2', 'tp2', dataType.currency);
+        addFields(tableDefine, prefix + '金额3', 'tp3', dataType.currency);
+        addFields(tableDefine, prefix + '金额4', 'tp4', dataType.currency);
+        addFields(tableDefine, prefix + '金额5', 'tp5', dataType.currency);
+        addFields(tableDefine, prefix + '金额6', 'tp6', dataType.currency);
+        addFields(tableDefine, prefix + '金额7', 'tp7', dataType.currency);
+        addFields(tableDefine, prefix + '金额8', 'tp8', dataType.currency);
+        addFields(tableDefine, prefix + '金额9', 'tp9', dataType.currency);
+        addFields(tableDefine, prefix + '金额10', 'tp10', dataType.currency);
+        yield saveTableDefine(ctx, tableDefine, ctx.app.baseDir + '/mem_union_data.json');
+    });
 });