Browse Source

report code sync for data

TonyKang 7 years ago
parent
commit
419d2513ff

+ 20 - 3
modules/main/models/project_consts.js

@@ -1,7 +1,7 @@
 /**
  * Created by jimiz on 2017/4/18.
  */
-var projectConst = {
+let projectConst = {
     BILLS: 'bills',
     RATION: 'ration',
     GLJ: 'GLJ',
@@ -18,10 +18,27 @@ var projectConst = {
     LABOUR_COE:'labour_coe'
 };
 
-var commonConst = {
+let projectConstList = [
+    'bills',
+    'ration',
+    'GLJ',
+    'ration_glj',
+    'ration_coe',
+    'ration_ass',
+    'quantity_detail',
+    'projectGLJ',
+    'GLJList',
+    'unitPriceFile',
+    'properties',
+    'volume_price',
+    'feeRate',
+    'labour_coe'
+];
+
+let commonConst = {
     UT_UPDATE: 'ut_update',
     UT_CREATE: 'ut_create',
     UT_DELETE: 'ut_delete'
 };
 
-module.exports = {projectConst: projectConst, commonConst: commonConst};
+module.exports = {projectConst: projectConst, commonConst: commonConst, projectConstList: projectConstList};

+ 25 - 6
modules/reports/facade/rpt_tpl_data_facade.js

@@ -2,13 +2,32 @@
  * Created by Tony on 2017/8/9.
  */
 
-import mongoose from "mongoose";
-let rpt_tpl_mdl = mongoose.model("rpt_templates");
+// import mongoose from "mongoose";
+// let consts = require('../../../modules/main/models/project_consts');
+// let projectConst = consts.projectConst;
+let prjMdl = require('../../../modules/pm/models/project_model');
+let projectDataMdl = require('../../../modules/main/models/project');
 
 module.exports = {
+    prepareProjectData: prepareProjectData
+};
 
-}
-
-async function prepareProjectData(prjId, userId) {
-    //
+function prepareProjectData(userId, prjId, filter, callback) {
+    let rawDataObj = null;
+    prjMdl.project.getUserProject(userId, prjId, function(err, msg, rst){
+        if (!err) {
+            rawDataObj = {};
+            rawDataObj.prj = rst;
+            projectDataMdl.getFilterData(prjId, filter, function (results) {
+                if (results) {
+                    rawDataObj.prjData = results;
+                    callback(false, 'Succeeded!', rawDataObj);
+                } else {
+                    callback(true, 'No data were found!', null);
+                }
+            });
+        } else {
+            callback(err, msg, null);
+        }
+    });
 }

+ 254 - 0
modules/reports/util/rpt_construct_data_util.js

@@ -0,0 +1,254 @@
+/**
+ * Created by Tony on 2017/7/14.
+ * 报表数据提取class,是协助报表模板里指标字段自主提取数据的工具类
+ */
+let JV = require('../rpt_component/jpc_value_define');
+let $JE = require('../rpt_component/jpc_rte');
+let consts = require('../../../modules/main/models/project_consts');
+let projectConst = consts.projectConst;
+let projectConstList = consts.projectConstList;
+
+class Rpt_Common{
+    initialize(Projects) {
+        this.Projects = Projects;
+    };
+
+    getSerialNo(fieldId, $CURRENT_RPT, $CURRENT_DATA){
+        let itemSerialNoRec = $JE.F(fieldId, $CURRENT_RPT);
+        if (itemSerialNoRec) {
+            itemSerialNoRec[JV.PROP_AD_HOC_DATA] = [];
+            for (var innerFmlIdx = 0; innerFmlIdx < $CURRENT_DATA[JV.DATA_DETAIL_DATA][0].length; innerFmlIdx++) {
+                itemSerialNoRec[JV.PROP_AD_HOC_DATA][innerFmlIdx] = (innerFmlIdx + 1);
+            }
+            itemSerialNoRec = null;
+        }
+    };
+}
+
+class Rpt_Data_Extractor {
+    constructor () {
+        this.COMMON = new Rpt_Common();
+    };
+
+    initialize(tpl) {
+        this.rptTpl = tpl;
+    };
+
+    getDataRequestFilter() {
+        let rst = [];
+        let tpl = this.rptTpl;
+        let pri_func_chk_filter = function (field) {
+            for (let key of projectConstList) {
+                if (rst.indexOf(key) < 0) {
+                    if (field[JV.PROP_FIELD_EXP_MAP]) {
+                        if (field[JV.PROP_FIELD_EXP_MAP].indexOf('.' + key + '.') >= 0) {
+                            rst.push(key);
+                        }
+                    }
+                }
+            }
+        };
+        if (tpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS]) {
+            for (let field of tpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS]) {
+                pri_func_chk_filter(field);
+            }
+        }
+        if (tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS]) {
+            for (let field of tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS]) {
+                pri_func_chk_filter(field);
+            }
+        }
+        if (tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS]) {
+            for (let field of tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS]) {
+                pri_func_chk_filter(field);
+            }
+        }
+        if (tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX]) {
+            for (let field of tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX]) {
+                pri_func_chk_filter(field);
+            }
+        }
+        if (tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX]) {
+            for (let field of tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX]) {
+                pri_func_chk_filter(field);
+            }
+        }
+        return rst;
+    };
+
+    //--- 装配数据(把收集到的数据,依据报表模板的指示,预处理(如:排序、过滤、合计)及装配到相关指标) ---//
+    assembleData(rawDataObj) {
+        let $PROJECT = {"COMMON": {}, "MAIN": {}, "DETAIL": {}};
+        let tpl = this.rptTpl;
+        $PROJECT.MAIN["myOwnRawDataObj"] = rawDataObj.prj._doc;
+        $PROJECT.MAIN.getProperty = ext_mainGetPropety;
+        $PROJECT.MAIN.getFee = ext_mainGetFee;
+        $PROJECT.DETAIL.getRationPropertyByID = ext_getRationPropertyByID;
+        if (tpl[JV.NODE_MAP_DATA_HANDLE_INFO]) {
+            for (let preHandle of tpl[JV.NODE_MAP_DATA_HANDLE_INFO]) {
+                switch(preHandle[JV.PROP_HANDLE_TYPE]) {
+                    case JV.PROP_HANDLE_TYPE_SORT:
+                        break;
+                    case JV.PROP_HANDLE_TYPE_FILTER:
+                        break;
+                    case JV.PROP_HANDLE_TYPE_SUM:
+                        //
+                }
+            }
+        }
+        for (let item of rawDataObj.prjData) {
+            setupFunc($PROJECT.DETAIL, item.moduleName, item);
+        }
+        let rptDataObj = {};
+        rptDataObj[JV.DATA_DISCRETE_DATA] = [];
+        rptDataObj[JV.DATA_MASTER_DATA] = [];
+        rptDataObj[JV.DATA_DETAIL_DATA] = [];
+        rptDataObj[JV.DATA_MASTER_DATA_EX] = [];
+        rptDataObj[JV.DATA_DETAIL_DATA_EX] = [];
+        assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS], rptDataObj[JV.DATA_DISCRETE_DATA], $PROJECT);
+        // console.log(JV.DATA_DISCRETE_DATA);
+        // console.log(rptDataObj[JV.DATA_DISCRETE_DATA]);
+        assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS], rptDataObj[JV.DATA_MASTER_DATA], $PROJECT);
+        // console.log(JV.DATA_MASTER_DATA);
+        // console.log(rptDataObj[JV.DATA_MASTER_DATA]);
+        assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS], rptDataObj[JV.DATA_DETAIL_DATA], $PROJECT);
+        // console.log(JV.DATA_DETAIL_DATA);
+        // console.log(rptDataObj[JV.DATA_DETAIL_DATA]);
+        assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX], rptDataObj[JV.DATA_MASTER_DATA_EX], $PROJECT);
+        // console.log(JV.DATA_MASTER_DATA_EX);
+        // console.log(rptDataObj[JV.DATA_MASTER_DATA_EX]);
+        assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX], rptDataObj[JV.DATA_DETAIL_DATA_EX], $PROJECT);
+        // console.log(JV.DATA_DETAIL_DATA_EX);
+        // console.log(rptDataObj[JV.DATA_DETAIL_DATA_EX]);
+    };
+
+}
+
+function setupFunc(obj, prop, ownRawObj) {
+    obj[prop] = {};
+    obj[prop]["myOwnRawDataObj"] = ownRawObj;
+    obj[prop].getProperty = ext_getPropety;
+    obj[prop].getFee = ext_getFee;
+}
+
+function assembleFields(fieldList, rstDataArr, $PROJECT) {
+    if (fieldList) {
+        for (let field of fieldList) {
+            shielded_exec_env($PROJECT, field, rstDataArr);
+        }
+    }
+}
+
+function shielded_exec_env($PROJECT, $ME, rptDataItemObj) {
+    if ($ME[JV.PROP_FIELD_EXP_MAP]) {
+        rptDataItemObj.push(eval($ME[JV.PROP_FIELD_EXP_MAP]));
+    }
+}
+
+function ext_mainGetPropety(propKey) {
+    let rst = [];
+    let parentObj = this;
+    //console.log(this);
+    let dtObj = parentObj["myOwnRawDataObj"];
+    if ((dtObj) && (propKey)) {
+        if (dtObj.hasOwnProperty("property")) {
+            rst.push(dtObj["property"][propKey]);
+        } else  {
+            rst.push(dtObj[propKey]);
+        }
+    }
+    return rst;
+}
+
+function ext_mainGetFee(feeKey) {
+    let rst = [];
+    let parentObj = this;
+    let dtObj = parentObj["myOwnRawDataObj"];
+    if ((dtObj) && (feeKey)) {
+        if (dtObj.hasOwnProperty("fees")) {
+            for (let fee of dtObj["fees"]) {
+                if (fee["fieldName"] === feeKey) {
+                    rst.push(dtObj["fees"][feeKey]);
+                    break;
+                }
+            }
+        } else if (dtObj.hasOwnProperty(feeKey)) {
+            rst.push(dtObj[feeKey]);
+        } else {
+            //
+        }
+    }
+    return rst;
+}
+
+function ext_getPropety(propKey) {
+    let rst = [], parentObj = this;
+    let dtObj = parentObj["myOwnRawDataObj"];
+    if (propKey && dtObj) {
+        for (let dItem of dtObj.data) {
+            let doc = dItem._doc;
+            if (doc.hasOwnProperty("property")) {
+                rst.push(doc["property"][propKey]);
+            } else if (doc.hasOwnProperty(propKey)) {
+                rst.push(doc[propKey]);
+            } else {
+                rst.push('');
+            }
+        }
+    }
+    return rst;
+}
+
+function ext_getFee(feeKey) {
+    let rst = [], parentObj = this;
+    let dtObj = parentObj["myOwnRawDataObj"];
+    if (feeKey && dtObj) {
+        for (let dItem of dtObj.data) {
+            if (dItem.hasOwnProperty("fees")) {
+                for (let fee of dItem["fees"]) {
+                    if (fee["fieldName"] === feeKey) {
+                        rst.push(dItem["fees"][feeKey]);
+                        break;
+                    }
+                }
+            } else if (dItem.hasOwnProperty(feeKey)) {
+                rst.push(dItem[feeKey]);
+            } else {
+                rst.push[0];
+            }
+        }
+    }
+    return rst;
+}
+
+function ext_getRationPropertyByID(IdVal, propKey) {
+    let rst = [], me = this;
+    if (IdVal !== null && IdVal !== undefined && me[projectConst.RATION]) {
+        let isFound = false;
+        if (IdVal instanceof Array) {
+            for (let id of IdVal) {
+                isFound = false;
+                for (let item of me[projectConst.RATION]["myOwnRawDataObj"].data) {
+                    if (item.ID === id) {
+                        rst.push(item[propKey]);
+                        isFound = true;
+                        break;
+                    }
+                }
+                // if (!isFound) rst.push[null];
+            }
+        } else {
+            for (let item of me[projectConst.RATION]["myOwnRawDataObj"].data) {
+                if (item.ID === IdVal) {
+                    rst.push(item[propKey]);
+                    isFound = true;
+                    break;
+                }
+            }
+            // if (!isFound) rst.push[null];
+        }
+    }
+    return rst;
+}
+
+export default Rpt_Data_Extractor;

+ 0 - 66
modules/reports/util/rpt_data_util.js

@@ -1,66 +0,0 @@
-/**
- * Created by Tony on 2017/7/14.
- * 报表数据提取class,是协助报表模板里指标字段自主提取数据的工具类
- */
-let JV = require('../rpt_component/jpc_value_define');
-let $JE = require('../rpt_component/jpc_rte');
-
-class Rpt_Common{
-    initialize(Projects) {
-        this.Projects = Projects;
-    };
-
-    getSerialNo(fieldId, $CURRENT_RPT, $CURRENT_DATA){
-        let itemSerialNoRec = $JE.F(fieldId, $CURRENT_RPT);
-        if (itemSerialNoRec) {
-            itemSerialNoRec[JV.PROP_AD_HOC_DATA] = [];
-            for (var innerFmlIdx = 0; innerFmlIdx < $CURRENT_DATA[JV.DATA_DETAIL_DATA][0].length; innerFmlIdx++) {
-                itemSerialNoRec[JV.PROP_AD_HOC_DATA][innerFmlIdx] = (innerFmlIdx + 1);
-            }
-            itemSerialNoRec = null;
-        }
-    };
-};
-
-class Rpt_Data_Extractor {
-    constructor () {
-        this.COMMON = new Rpt_Common();
-    };
-
-    initialize(Projects) {
-        this.Projects = Projects;
-        //Projects对象应该从前端传送过来,无需在后端重复查询及构建
-        /* 结构:
-         {
-            currentPrjId: int,
-            topPrj: [
-                //单项工程
-                {
-                    subPrjName: String,
-                    subPrjId: int,
-                    detailPrj: [
-                        //单位工程
-                        {
-                            detailPrjName: String,
-                            subPrjId: int,
-                        }
-                        ...
-                    ]
-                }
-                ...
-            ]
-         }
-         */
-    };
-
-    prepareData($CURRENT_RPT) {
-        //在报表提取数据前的准备工作,主要有:
-        //1. 确认指标数据的类型(离散/主/从)
-        //2. 根据类型提取数据,排序
-        // 2.1. header类型
-        // 2.2. 章类型
-        // 2.3. detail类型
-        // 2.4. 排序
-    };
-
-}

+ 14 - 1
public/web/rpt_value_define.js

@@ -35,7 +35,6 @@ const JV = {
     DISPLAY_MODE_INDEPENDENT: "单独模式",
     DISPLAY_MODE_FOLLOW: "紧随模式",
 
-
     NODE_MAIN_INFO: "主信息",
     NODE_MAIN_INFO_RPT_NAME: "报表名称",
     NODE_PAGE_INFO: "打印页面_信息",
@@ -46,6 +45,20 @@ const JV = {
     NODE_BIZ_TYPE_SUM: "汇总类型",
     NODE_BIZ_TYPE_DETAIL: "明细类型",
 
+    NODE_MAP_DATA_HANDLE_INFO: "映射数据过滤及统计处理",
+    PROP_DATA_KEY: "映射数据对象",
+    PROP_HANDLE_TYPE: "预处理类型",
+    PROP_FILTER_KEY: "过滤键属性",
+    PROP_FILTER_DEPENDENT_ON: "过滤依据对象",
+    PROP_FILTER_DEPENDENT_ON_KEY: "过滤依据对象键属性",
+    PROP_FILTER_CONDITION: "条件",
+    PROP_HANDLE_TYPE_FILTER: "过滤",
+    PROP_HANDLE_TYPE_SUM: "合计",
+    PROP_HANDLE_TYPE_SORT: "排序",
+    PROP_SUM_GROUP_KEYS: "分组键值集",
+    PROP_SUM_SUM_KEYS: "统计键值集",
+    PROP_FIELD_EXP_MAP: "mapExpression",
+
     NODE_FONT_COLLECTION: "font_collection",
     NODE_STYLE_COLLECTION: "style_collection",
     NODE_CONTROL_COLLECTION: "control_collection",

+ 126 - 0
test/unit/reports/test_tpl_09_1.js

@@ -0,0 +1,126 @@
+/**
+ * Created by Tony on 2017/10/18.
+ */
+let test = require('tape');
+import JV from "../../../modules/reports/rpt_component/jpc_value_define";
+let mongoose = require("mongoose");
+let fileUtils = require("../../../modules/common/fileUtils");
+let path = require('path');
+let dbm = require("../../../config/db/db_manager");
+dbm.connect();
+let consts = require('../../../modules/main/models/project_consts');
+let projectConsts = consts.projectConst;
+fileUtils.getGlobbedFiles('../../../modules/complementary_glj_lib/models/*.js').forEach(function(modelPath) {
+    require(path.resolve(modelPath));
+});
+
+fileUtils.getGlobbedFiles('../../../modules/ration_glj/models/*.js').forEach(function(modelPath) {
+    require(path.resolve(modelPath));
+});
+
+//引入报表模块
+fileUtils.getGlobbedFiles('../../../modules/reports/models/*.js').forEach(function(modelPath) {
+    require(path.resolve(modelPath));
+})
+
+//暂时引入其它模块的model
+require('../../../modules/fee_rates/models/fee_rates');
+// 引入人工系数模块
+require('../../../modules/main/models/labour_coe');
+
+let fsUtil = require("../../../public/fsUtil");
+
+let prjMdl = require('../../../modules/pm/models/project_model');
+let projectDataMdl = require('../../../modules/main/models/project');
+let demoPrjId = - 1;
+let demoRptId = 226, pagesize = "A4";
+
+demoPrjId = 469; //QA: 1号教学楼建筑工程
+// demoPrjId = 491; //QA: 2号教学楼建筑工程
+// demoPrjId = 492; //QA: 3号教学楼建筑工程
+let userId_Leng = 1142; //小冷User Id
+
+let rptTplFacade = require("../../../modules/reports/facade/rpt_template_facade");
+let rptTplDataFacade = require("../../../modules/reports/facade/rpt_tpl_data_facade");
+
+import rptDataExtractor from "../../../modules/reports/util/rpt_construct_data_util";
+
+// test('测试 - 获取project数据: ', function (t) {
+//     projectDataMdl.getData(demoPrjId, function (err, message, result) {
+//         if (!err) {
+//             fsUtil.wirteObjToFile(result, "D:/GitHome/ConstructionCost/tmp/ProjectDataFullObject.js");
+//             t.pass('pass succeeded!');
+//             t.end();
+//         } else {
+//             //callback(req, res, err, message, null);
+//             t.pass('pass failed!');
+//             t.end();
+//         }
+//     });
+// });
+
+// test('测试 - 获取project部分数据: ', function (t) {
+//     let filter = [];
+//     filter.push(projectConsts.BILLS);
+//     filter.push(projectConsts.RATION);
+//     filter.push(projectConsts.RATION_GLJ);
+//     filter.push(projectConsts.FEERATE);
+//     prjMdl.project.getUserProject(userId_Leng, demoPrjId, function(err, msg, prjObj){
+//         if (!err) {
+//             projectDataMdl.getFilterData(demoPrjId, filter, function (results) {
+//                 if (results) {
+//                     // let newData = [];
+//                     // for (let item of results) {
+//                     //     newData.push(JSON.stringify(item));
+//                     // }
+//                     // fsUtil.writeArrayToFile(newData, "D:/GitHome/ConstructionCost/tmp/getProjectData_partial.js");
+//                     fsUtil.wirteObjToFile(prjObj, "D:/GitHome/ConstructionCost/tmp/getProjectObjectNew.js");
+//                     fsUtil.wirteObjToFile(results, "D:/GitHome/ConstructionCost/tmp/getProjectData_partialNew.js");
+//                     t.pass('pass succeeded!');
+//                     t.end();
+//                 } else {
+//                     //callback(req, res, err, message, null);
+//                     t.pass('get project data failed!');
+//                     t.end();
+//                 }
+//             });
+//         } else {
+//             t.pass('get project failed!');
+//             t.end();
+//         }
+//     });
+// });
+
+test('测试 - 测试模板啦: ', function (t) {
+    rptTplFacade.getRptTemplate(demoRptId).then(function(tpl) {
+        let rptDataUtil = new rptDataExtractor();
+        rptDataUtil.initialize(tpl);
+        let filter = rptDataUtil.getDataRequestFilter();
+        console.log(filter);
+        //正常应该根据报表模板定义的数据类型来请求数据
+        rptTplDataFacade.prepareProjectData(userId_Leng, demoPrjId, filter, function (err, msg, rawDataObj) {
+            if (!err) {
+                rptDataUtil.assembleData(rawDataObj);
+                t.pass('pass succeeded!');
+                t.end();
+                //fsUtil.wirteObjToFile(rawDataObj, "D:/GitHome/ConstructionCost/tmp/rptTplRawDataObject1.js");
+                //准备执行公式需要的对象
+            } else {
+                console.log(msg);
+                t.pass('pass with error!');
+                t.end();
+            }
+        })
+    });
+});
+
+test('close the connection', function (t) {
+    setTimeout(function () {
+        mongoose.disconnect();
+        t.pass('closing db connection');
+        t.end();
+    }, 3000);
+    // mongoose.disconnect();
+    // t.pass('closing db connection');
+    // t.end();
+});