浏览代码

Merge branch 'master' of http://192.168.1.41:3000/maixinrong/Calculation

TonyKang 5 年之前
父节点
当前提交
0e63b136cb

+ 1 - 1
app/controller/report_controller.js

@@ -166,7 +166,6 @@ module.exports = app => {
             rptTpl = JSON.parse(rptTpl[0].rpt_content);
             // console.log('get the template!');
             const customSelect = await ctx.service.rptCustomDefine.getCustomDefine(params.tender_id, params.stage_id, params.rpt_tpl_id);
-            console.log(customSelect);
             const pageRst = await getAllPagesCommon(ctx, rptTpl, params, JV.PAGING_OPTION_NORMAL, JV.OUTPUT_TYPE_NORMAL, this.app.baseDir, customSelect);
             // console.log(pageRst);
             // const roleRel = (params.stage_status === 3) ? (await ctx.service.roleRptRel.getRoleRptRelByDetailIds(params.tender_id, params.rpt_tpl_id)) : [];
@@ -539,6 +538,7 @@ async function getAllPagesCommon(ctx, rptTpl, params, option, outputType, baseDi
     const filter = rptDataUtil.getDataRequestFilter();
     // console.log(filter.tables);
     const rawDataObj = await ctx.service.report.getReportData(params, filter.tables, filter.memFieldKeys);
+    await ctx.helper.saveBufferFile(JSON.stringify(rawDataObj,"","\t"), ctx.app.baseDir + '/mem.json');
     // console.log(rawDataObj);
     try {
         const printCom = JpcEx.createNew();

+ 5 - 3
app/lib/ledger.js

@@ -334,10 +334,12 @@ class pos {
     /**
      * 计算全部
      */
-    calculateAll() {
-        if (!this.setting.calc) { return; }
+    calculateAll(fun) {
+        const calcFun = fun ? fun : this.setting.calc;
+        if (!calcFun) return;
+
         for (const pos of this.datas) {
-            this.setting.calc(pos);
+            calcFun(pos);
         }
     }
 

+ 19 - 1
app/lib/rpt_data_analysis.js

@@ -834,7 +834,7 @@ const auditSelect = {
     name: '审批人选择',
     hint: '需搭配用户交互--审批人选择一起使用',
     defaultSetting: {
-        table: ['mem_stage_bills_compare'],
+        table: ['mem_stage_bills_compare', 'mem_stage_pos_compare'],
     },
     _stageBillsCompare(data, order) {
         const fields = [];
@@ -854,6 +854,21 @@ const auditSelect = {
             }
         }
     },
+    _stagePosCompare(data, order) {
+        const fields = [];
+        for (const [i, o] of order.entries()) {
+            const sPrefix = 'r' + o + '_';
+            const tPrefix = 'as' + i + '_';
+            fields.push({source: sPrefix + 'contract_qty', target: tPrefix + 'contract_qty'});
+            fields.push({source: sPrefix + 'qc_qty', target: tPrefix + 'qc_qty'});
+            fields.push({source: sPrefix + 'gather_qty', target: tPrefix + 'gather_qty'});
+        }
+        for (const d of data) {
+            for (const f of fields) {
+                d[f.target] = d[f.source];
+            }
+        }
+    },
     fun: function (ctx, data, fieldsKey, options, csRela) {
         if (!ctx.tender || !ctx.stage) return;
         if (!csRela.tplDefine) return;
@@ -878,6 +893,9 @@ const auditSelect = {
                 case 'mem_stage_bills_compare':
                     this._stageBillsCompare(data[t], order);
                     break;
+                case 'mem_stage_pos_compare':
+                    this._stagePosCompare(data[t], order);
+                    break;
             }
         }
     }

+ 36 - 6
app/public/report/js/rpt_custom.js

@@ -9,20 +9,33 @@
  */
 
 const rptCustomObj = (function () {
-
     const sAuditSelect = 'audit_select';
     let stageFlow = [];
 
-    const getStageFlowSelectHtml = function (select) {
+    const getStageFlowSelectHtml = function (select, id) {
         const html = [];
-        html.push('<select style="width: 80%">');
+        html.push('<select style="width: 80%" id="' + id + '" sf-title="' + select.title + '">');
         for (const sf of stageFlow) {
-            html.push('<option' + (select && sf.order === select.order ? ' selected' : '') + '>' + sf.name + '-' + sf.role +'</option>');
+            html.push('<option>' + sf.name + '-' + sf.role +'</option>');
         }
         html.push('</select>');
         return html.join('');
     };
 
+    const checkAsSelectValid = function (validFlow, asSelect) {
+        for (const s of asSelect) {
+            const f = validFlow.find(function (x) {
+                return x.aid === s.aid && x.order === s.order;
+            });
+            if (!f) {
+                $('#audit-select-hint').html('本期审批流程发生变动,原审批人选择不适配,需重新选择').show();
+                return false;
+            }
+        }
+        $('#audit-select-hint').hide();
+        return true;
+    };
+
     const initAuditSelect = function (asSetting, asSelect) {
         const setting = JSON.parse(asSetting), select = asSelect;
         $('#audit-select-title').html(setting.title);
@@ -30,10 +43,21 @@ const rptCustomObj = (function () {
         for (const [i, s] of setting.select.entries()) {
             html.push('<tr>');
             html.push('<td>', s.title, '</td>');
-            html.push('<td>', getStageFlowSelectHtml(select[i]), '</td>');
+            html.push('<td>', getStageFlowSelectHtml(s, 'sf-' + i), '</td>');
             html.push('</tr>');
         }
         $('#audit-select-list').html(html.join(''));
+        for (const [i, s] of setting.select.entries()) {
+            const obj = $('#sf-' + i);
+            const s = select[i];
+            const sf = s ? stageFlow.find(function (x) {
+                return x.order === s.order && x.aid === s.aid;
+            }) : null;
+            obj[0].selectedIndex = sf ? sf.order : -1;
+        }
+        if (asSelect.length === 0 || !checkAsSelectValid(stageFlow, asSelect)) {
+            $('#audit-select').modal('show');
+        }
     };
 
     const init = function (cDefine, sfData, cSelect) {
@@ -118,8 +142,14 @@ const rptCustomObj = (function () {
         data.stage_order = getStageOrder();
         data.stage_times = getStageTimes();
         for (const s of selObj) {
-            data.audit_select.push(stageFlow[s.selectedIndex]);
+            const sf = stageFlow[s.selectedIndex];
+            if (!sf) {
+                $('#audit-select-hint').html('未选择' + s.attributes['sf-title'].value).show();
+                return;
+            }
+            data.audit_select.push(sf);
         }
+        $('#audit-select-hint').hide();
         postData('/report/cDefine', data, function (result) {
             reloadReportData(result);
             $('#audit-select').modal('hide');

+ 0 - 1
app/public/upload/changes/page.html

@@ -1 +0,0 @@
-当前页存变更令附件

+ 0 - 1
app/public/upload/pay/page.html

@@ -1 +0,0 @@
-当前页存合同支付附件

+ 0 - 1
app/public/upload/qrcode/page.html

@@ -1 +0,0 @@
-当前页存签名图片

二进制
app/public/upload/sign/20190926_sign_1569481904.png


二进制
app/public/upload/sign/20190926_sign_1569481905.png


二进制
app/public/upload/sign/20190926_sign_1569482230.png


二进制
app/public/upload/sign/20190926_sign_kt.png


+ 0 - 1
app/public/upload/sign/page.html

@@ -1 +0,0 @@
-当前页存签名图片

二进制
app/public/upload/sign/user-sign.PNG


+ 0 - 1
app/public/upload/stage/page.html

@@ -1 +0,0 @@
-当前页存计量台账附件

+ 2 - 1
app/reports/rpt_component/jpc_flow_tab.js

@@ -1152,7 +1152,8 @@ JpcFlowTabSrv.prototype.createNew = function() {
                             if (contentValuesIdx[rowIdx][2] >= 0) {
                                 const psv = JpcFieldHelper.getValue(page_sum_data_fields[di], contentValuesIdx[rowIdx][2]);
                                 if (psv) {
-                                    rowGrandTotal[di] = rowGrandTotal[di] + parseFloat(parseFloat(psv).toFixed(precisionAmt));
+                                    rowGrandTotal[di] = bc.add(rowGrandTotal[di] ? rowGrandTotal[di] : 0 , parseFloat(psv));
+                                    //rowGrandTotal[di] = rowGrandTotal[di] + parseFloat(parseFloat(psv).toFixed(precisionAmt));
                                 }
                             }
                         }

+ 2 - 3
app/reports/util/rpt_calculation_data_util.js

@@ -572,17 +572,16 @@ function preDefineProcess(ctx, tpl, preDefineCfg, rawDataObj, $CURRENT_RPT, cust
             try {
                 // 在预定义方式中,小麦处理原始数据,不需要
                 let preSetup = preDefineCfg[JV.PROP_HANDLE_SELF_SETUP];
-                console.log(preSetup);
                 try {
                     if (preSetup) {
                         preSetup = JSON.parse(preSetup);
                     }
                 } catch (ex) {
-                    console.log(analysisKey);
                     ctx.helper.log(ex);
                 }
                 data_analyze_util[analysisKey].fun(ctx, rawDataObj, fields, preSetup, {
-                    tplDefine: tpl[JV.NODE_CUS_AUDIT_SELECT], cDefine: customSelect
+                    tplDefine: tpl[JV.NODE_CUSTOM_DEFINE],
+                    cDefine: customSelect
                 });
             } catch (err) {
                 ctx.helper.log(err);

+ 25 - 10
app/service/change.js

@@ -226,23 +226,22 @@ module.exports = app => {
             switch (status) {
                 case 0:// 包含你的所有变更令
                     sql = 'SELECT a.* FROM ?? AS a WHERE a.tid = ? AND ' +
-                        '(a.uid = ? OR (a.status != 1 AND a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? AND a.times = b.times GROUP BY b.cid))) ORDER BY a.in_time DESC';
-                    sqlParam = [this.tableName, tenderId, this.ctx.session.sessionUser.accountId,
-                        this.ctx.service.changeAudit.tableName, this.ctx.session.sessionUser.accountId];
+                        '(a.uid = ? OR (a.status != ? AND a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? AND a.times = b.times GROUP BY b.cid)) OR a.status = ? ) ORDER BY a.in_time DESC';
+                    sqlParam = [this.tableName, tenderId, this.ctx.session.sessionUser.accountId, audit.flow.status.uncheck,
+                        this.ctx.service.changeAudit.tableName, this.ctx.session.sessionUser.accountId, audit.flow.status.checked];
                     break;
                 case 1:// 待处理(你的)
                     sql = 'SELECT a.* FROM ?? as a WHERE cid in(SELECT b.cid FROM ?? as b WHERE tid = ? AND uid = ? AND status = ?) ORDER BY in_time DESC';
-                    sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId, this.ctx.session.sessionUser.accountId, 2];
+                    sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId, this.ctx.session.sessionUser.accountId, audit.flow.auditStatus.checking];
                     break;
                 case 5:// 待上报(所有的)PS:取未上报和退回的变更令
                     sql = 'SELECT a.* FROM ?? AS a WHERE ' +
                         'a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? GROUP BY b.cid) AND ' +
-                        '(a.status = 1 OR a.status = 5) AND a.tid = ? ORDER BY a.in_time DESC';
+                        '(a.status = ? OR a.status = ?) AND a.tid = ? ORDER BY a.in_time DESC';
                     sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName,
-                        this.ctx.session.sessionUser.accountId, tenderId];
+                        this.ctx.session.sessionUser.accountId, audit.flow.status.uncheck, audit.flow.status.back, tenderId];
                     break;
                 case 2:// 进行中(所有的)
-                case 3:// 已完成(所有的)
                 case 4:// 终止(所有的)
                     sql = 'SELECT a.* FROM ?? AS a WHERE ' +
                         'a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? AND a.times = b.times GROUP BY b.cid) AND ' +
@@ -250,6 +249,11 @@ module.exports = app => {
                     sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName,
                         this.ctx.session.sessionUser.accountId, status, tenderId];
                     break;
+                case 3:// 已完成(所有的)
+                    sql = 'SELECT a.* FROM ?? AS a WHERE ' +
+                        'a.status = ? AND a.tid = ? ORDER BY a.in_time DESC';
+                    sqlParam = [this.tableName, status, tenderId];
+                    break;
                 default:
                     break;
             }
@@ -286,13 +290,12 @@ module.exports = app => {
                 case 5:// 待上报(所有的)PS:取未上报和退回的变更令
                     const sql2 = 'SELECT count(*) AS count FROM ?? AS a WHERE ' +
                         'a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? AND a.times = b.times GROUP BY b.cid) ' +
-                        'AND (a.status = 1 OR a.status = 5) AND a.tid = ?';
+                        'AND (a.status = ? OR a.status = ?) AND a.tid = ?';
                     const sqlParam2 = [this.tableName, this.ctx.service.changeAudit.tableName,
-                        this.ctx.session.sessionUser.accountId, tenderId];
+                        this.ctx.session.sessionUser.accountId, audit.flow.status.uncheck, audit.flow.status.back, tenderId];
                     const result2 = await this.db.query(sql2, sqlParam2);
                     return result2[0].count;
                 case 2:// 进行中(所有的)
-                case 3:// 已完成(所有的)
                 case 4:// 终止(所有的)
                     const sql3 = 'SELECT count(*) AS count FROM ?? AS a WHERE ' +
                         'a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? AND a.times = b.times GROUP BY b.cid) AND a.status = ? AND a.tid = ?';
@@ -300,6 +303,11 @@ module.exports = app => {
                         this.ctx.session.sessionUser.accountId, status, tenderId];
                     const result3 = await this.db.query(sql3, sqlParam3);
                     return result3[0].count;
+                case 3:// 已完成(所有的)
+                    const sql4 = 'SELECT count(*) AS count FROM ?? WHERE status = ? AND tid = ?';
+                    const sqlParam4 = [this.tableName, status, tenderId];
+                    const result4 = await this.db.query(sql4, sqlParam4);
+                    return result4[0].count;
                 default:
                     break;
             }
@@ -1052,6 +1060,13 @@ module.exports = app => {
             const result = await this.db.queryOne(sql, sqlParam);
             return result.count !== 0;
         }
+
+        async getAllCheckedChanges(tid) {
+            return await this.getAllDataByCondition({
+                where: {tid: tid, status: audit.flow.status.checked},
+                orders: [['in_time', 'desc']]
+            })
+        }
     }
     return Change;
 };

+ 1 - 1
app/service/change_audit.js

@@ -99,7 +99,7 @@ module.exports = app => {
             const auditStatusConst = audit.flow.auditStatus;
             const uid = this.ctx.session.sessionUser.accountId;
             const changeAuditInfo = await this.getAllDataByCondition({ where: { cid: change.cid, times: change.times, uid }, orders: [['id', 'desc']], limit: 1, offset: 0 });
-            if (changeAuditInfo === null || changeAuditInfo[0].status === undefined) {
+            if (!change.status === statusConst.checked && (changeAuditInfo === null || changeAuditInfo[0] === undefined)) {
                 // 无权限查看此变更令
                 return 0;
             }

+ 2 - 5
app/service/report.js

@@ -94,11 +94,8 @@ module.exports = app => {
                             break;
                         case 'mem_stage_pay':
                             runnableRst.push(service.reportMemory.getStagePayData(params.tender_id, params.stage_id, memFieldKeys[filter]));
-                            runnableKey.push('mem_stage_pay');
-                        // case 'mem_change_bills':
-                        //     runnableRst.push(service.reportMemory.getChangeBillsData(params.tender_id, params.stage_id, memFieldKeys[filter]));
-                        //     runnableKey.push('mem_change_bills');
-                        //     break;
+                            runnableKey.push(filter);
+                            break;
                         case 'change':
                             runnableRst.push(service.change.getListByStatus(params.tender_id, 3)); // 获取所有审核通过的变更主信息
                             runnableKey.push(filter);

+ 135 - 53
app/service/report_memory.js

@@ -24,14 +24,30 @@ const stageImVersion = '1.0';
 
 const Ledger = require('../lib/ledger');
 
-const curFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'gather_qty', 'gather_tp', 'postil'];
-const preFields = ['pre_contract_qty', 'pre_contract_tp', 'pre_qc_qty', 'pre_qc_tp', 'pre_gather_qty', 'pre_gather_tp'];
-const endFields = ['end_contract_qty', 'end_contract_tp', 'end_qc_qty', 'end_qc_tp', 'end_gather_qty', 'end_gather_tp'];
-const finalFields = ['final_tp', 'final_ratio'];
-
-const stageFields = curFields.concat(preFields, endFields, finalFields);
-const stageEndFields = preFields.concat(endFields, finalFields);
-const bglFields = ['qc_bgl_code'];
+const billsFields = (function () {
+    const cur = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'gather_qty', 'gather_tp', 'postil'];
+    const pre = ['pre_contract_qty', 'pre_contract_tp', 'pre_qc_qty', 'pre_qc_tp', 'pre_gather_qty', 'pre_gather_tp'];
+    const end = ['end_contract_qty', 'end_contract_tp', 'end_qc_qty', 'end_qc_tp', 'end_gather_qty', 'end_gather_tp'];
+    const final = ['final_tp', 'final_ratio'];
+
+    const stage = cur.concat(pre, end, final);
+    const stageEnd = pre.concat(end, final);
+    const bgl = ['qc_bgl_code'];
+
+    return {cur, pre, end, final, stage, stageEnd, bgl};
+})();
+const posFields = (function () {
+    const cur = ['contract_qty', 'qc_qty', 'gather_qty', 'postil'];
+    const pre = ['pre_contract_qty', 'pre_qc_qty', 'pre_gather_qty'];
+    const end = ['end_contract_qty', 'end_qc_qty', 'end_gather_qty'];
+    const final = ['final_ratio'];
+
+    const stage = cur.concat(pre, end, final);
+    const stageEnd = pre.concat(end, final);
+    const bgl = ['qc_bgl_code'];
+
+    return {cur, pre, end, final, stage, stageEnd, bgl};
+})();
 
 module.exports = app => {
     class ReportMemory extends app.BaseService {
@@ -89,6 +105,7 @@ module.exports = app => {
             // 需要缓存的数据
             this.stageImData = null;
             this.changeData = null;
+            this.stageValidRole = [];
         }
 
         _checkFieldsExist(source, check) {
@@ -175,30 +192,6 @@ module.exports = app => {
             }
         }
 
-        async getStageImTzNoReturn(tid, sid) {
-            // 备注:单独拎出以下几行代码一个是为了提高效率(跟getStageImTzDataDirectlyByKey方法协作使用)
-            //      二是如果出现并行查询(台账及台账清单)情况下,会出现干扰(已验证过),导致数据丢失
-            if (!this.stageImData) {
-                this.stageImData = {};
-            }
-            try {
-                await this._generateStageIm(tid, sid);
-            } catch (err) {
-                this.stageImData.main = [];
-                this.stageImData.bills = [];
-            }
-        }
-
-        getStageImTzDataDirectlyByKey(key) {
-            let rst = [];
-            if (key === 'mem_stage_im_tz') {
-                rst = this.stageImData.main;
-            } else {
-                rst = this.stageImData.bills;
-            }
-            return rst;
-        }
-
         async getStageImTzData(tid, sid, fields) {
             await this.ctx.service.tender.checkTender(tid);
             await this.ctx.service.stage.checkStage(sid);
@@ -342,7 +335,7 @@ module.exports = app => {
             }
 
             const billsData = await this.ctx.service.ledger.getData(this.ctx.tender.id);
-            if (this._checkFieldsExist(fields, stageFields)) {
+            if (this._checkFieldsExist(fields, billsFields.stage)) {
                 if (this.ctx.stage.readOnly) {
                     const curStage = await this.ctx.service.stageBills.getAuditorStageData(this.ctx.tender.id,
                         this.ctx.stage.id, this.ctx.stage.curTimes, this.ctx.stage.curOrder);
@@ -356,7 +349,7 @@ module.exports = app => {
                     ]);
                 }
             }
-            if (this._checkFieldsExist(fields, preFields.concat(endFields, finalFields))) {
+            if (this._checkFieldsExist(fields, billsFields.stageEnd)) {
                 const preStage = this.ctx.stage.order > 1 ? await this.ctx.service.stageBillsFinal.getFinalData(this.ctx.tender, this.ctx.stage.order - 1) : [];
                 this.ctx.helper.assignRelaData(billsData, [
                     {data: preStage, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: 'pre_', relaId: 'lid'}
@@ -365,7 +358,7 @@ module.exports = app => {
             this.billsTree.loadDatas(billsData);
             this.billsTree.calculateAll();
 
-            if (this._checkFieldsExist(fields, bglFields)) {
+            if (this._checkFieldsExist(fields, billsFields.bgl)) {
                 await this._calcBillsBgl();
             }
 
@@ -385,35 +378,67 @@ module.exports = app => {
             ]);
         }
 
+        async _calcPosBgl() {
+            if (!this.ctx.stage) return;
+
+            const helper = this.ctx.helper;
+            const tender = this.ctx.tender;
+            const stage = this.ctx.stage;
+            const bglData = this.ctx.stage.readOnly
+                ? await this.ctx.service.stageChange.getAuditorAllStageData(tender.id, stage.id, stage.curTimes, stage.curOrder)
+                : await this.ctx.service.stageChange.getLastestAllStageData(tender.id, stage.id);
+
+            for (const p of this.pos.datas) {
+                p.qc_bgl_code = '';
+
+                const pBgl = helper._.filter(bglData, {lid: p.lid, pid: p.id});
+                if (pBgl.length === 0) continue;
+                helper._.pullAll(bglData, pBgl);
+                const validBgl = helper._.filter(pBgl, function (x) {
+                    return !helper.checkZero(x.qty);
+                });
+                p.qc_bgl_code = helper._.uniq(helper._.map(validBgl, 'c_code')).join(';');
+            }
+        }
+
         async getStagePosData(tid, sid, fields) {
             await this.ctx.service.tender.checkTender(tid);
             await this.ctx.service.stage.checkStage(sid);
 
             const posData = await this.ctx.service.pos.getAllDataByCondition({ where: {tid: this.ctx.tender.id }});
-            if (this.ctx.stage.readOnly) {
-                const curPosStage = await this.ctx.service.stagePos.getAuditorStageData2(this.ctx.tender.id,
-                    this.ctx.stage.id, this.ctx.stage.curTimes, this.ctx.stage.curOrder);
-                this.ctx.helper.assignRelaData(posData, [
-                    {data: curPosStage, fields: ['contract_qty', 'qc_qty'], prefix: '', relaId: 'pid'}
-                ]);
-            } else {
-                const curPosStage = await this.ctx.service.stagePos.getLastestStageData2(this.ctx.tender.id, this.ctx.stage.id);
+            if (this._checkFieldsExist(fields, posFields.stage)) {
+                if (this.ctx.stage.readOnly) {
+                    const curPosStage = await this.ctx.service.stagePos.getAuditorStageData2(this.ctx.tender.id,
+                        this.ctx.stage.id, this.ctx.stage.curTimes, this.ctx.stage.curOrder);
+                    this.ctx.helper.assignRelaData(posData, [
+                        {data: curPosStage, fields: ['contract_qty', 'qc_qty'], prefix: '', relaId: 'pid'}
+                    ]);
+                } else {
+                    const curPosStage = await this.ctx.service.stagePos.getLastestStageData2(this.ctx.tender.id, this.ctx.stage.id);
+                    this.ctx.helper.assignRelaData(posData, [
+                        {data: curPosStage, fields: ['contract_qty', 'qc_qty'], prefix: '', relaId: 'pid'}
+                    ]);
+                }
+            }
+            if (this._checkFieldsExist(fields, posFields.stageEnd)) {
+                const prePosStage = this.ctx.stage.order > 1 ? await this.ctx.service.stagePosFinal.getFinalData(this.ctx.tender, this.ctx.stage.order - 1) : [];
                 this.ctx.helper.assignRelaData(posData, [
-                    {data: curPosStage, fields: ['contract_qty', 'qc_qty'], prefix: '', relaId: 'pid'}
+                    {data: prePosStage, fields: ['contract_qty', 'qc_qty'], prefix: 'pre_', relaId: 'pid'}
                 ]);
             }
-            const prePosStage = this.ctx.stage.order > 1 ? await this.ctx.service.stagePosFinal.getFinalData(this.ctx.tender, this.ctx.stage.order - 1) : [];
-            this.ctx.helper.assignRelaData(posData, [
-                {data: prePosStage, fields: ['contract_qty', 'qc_qty'], prefix: 'pre_', relaId: 'pid'}
-            ]);
             this.pos.loadDatas(posData);
             this.pos.calculateAll();
 
+            if (this._checkFieldsExist(fields, posFields.bgl)) {
+                await this._calcPosBgl();
+            }
+
             return this.pos.getDatas();
         }
 
         _getStageValidRole () {
             if (!this.ctx.stage) throw '期数据错误,请重试';
+            if (this.stageValidRole && this.stageValidRole.length > 0) return;
 
             const result = [{dataOrder: 0, flowOrder: 0, uid: this.ctx.stage.user_id}];
             for (const auditor of this.ctx.stage.auditors) {
@@ -433,15 +458,16 @@ module.exports = app => {
                     }
                 }
             }
-            return result;
+            this.stageValidRole = result;
         };
 
         async getStageBillsCompareData(tid, sid, fields) {
             await this.ctx.service.tender.checkTender(tid);
             await this.ctx.service.stage.checkStage(sid);
+            await this._getStageValidRole();
 
             const stage = this.ctx.stage, helper = this.ctx.helper;
-            const validRole = this._getStageValidRole();
+            const validRole = this.stageValidRole;
             const billsData = await this.ctx.service.ledger.getData(this.ctx.tender.id);
             const allStageBills = await this.ctx.service.stageBills.getAllDataByCondition({where: {sid: sid}});
 
@@ -469,7 +495,7 @@ module.exports = app => {
                 ]);
             }
 
-            if (this._checkFieldsExist(fields, preFields.concat(endFields, finalFields))) {
+            if (this._checkFieldsExist(fields, billsFields.stageEnd)) {
                 const preStage = this.ctx.stage.order > 1 ? await this.ctx.service.stageBillsFinal.getFinalData(this.ctx.tender, this.ctx.stage.order - 1) : [];
                 this.ctx.helper.assignRelaData(billsData, [
                     {data: preStage, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: 'pre_', relaId: 'lid'}
@@ -521,6 +547,56 @@ module.exports = app => {
             // ]);
         }
 
+        async getStagePosCompareData(tid, sid, fields) {
+            await this.ctx.service.tender.checkTender(tid);
+            await this.ctx.service.stage.checkStage(sid);
+            await this._getStageValidRole();
+
+            const stage = this.ctx.stage, helper = this.ctx.helper;
+            const validRole = this.stageValidRole;
+
+            const allStagePos = await this.ctx.service.stagePos.getAllDataByCondition({where: {sid: sid}});
+            const posData = await this.ctx.service.pos.getAllDataByCondition({ where: {tid: this.ctx.tender.id }});
+            const prePosStage = this.ctx.stage.order > 1 ? await this.ctx.service.stagePosFinal.getFinalData(this.ctx.tender, this.ctx.stage.order - 1) : [];
+            this.ctx.helper.assignRelaData(posData, [
+                {data: prePosStage, fields: ['contract_qty', 'qc_qty'], prefix: 'pre_', relaId: 'pid'}
+            ]);
+            const stagePosIndex = {}, timesLen = 100;
+            for (const role of validRole) {
+                const stagePos = this.ctx.helper._.filter(allStagePos, function (x) {
+                    return x.times < stage.curTimes || (x.times === stage.curTimes && x.order <= role.dataOrder);
+                });
+                this.ctx.helper._.pullAll(allStagePos, stagePos);
+                for (const sp of stagePos) {
+                    const key = 'sp-' + sp.pid;
+                    const spi = stagePosIndex[key];
+                    if (spi) {
+                        if ((spi.times * timesLen + spi.order) < (sp.times * timesLen + sp.order)) stagePosIndex[key] = sp;
+                    } else {
+                        stagePosIndex[key] = sp;
+                    }
+                }
+                const filterStagePos = [];
+                for (const prop in stagePosIndex) {
+                    filterStagePos.push(stagePosIndex[prop]);
+                }
+                this.ctx.helper.assignRelaData(posData, [
+                    {data: filterStagePos, fields: ['contract_qty', 'qc_qty'], prefix: 'r' + role.flowOrder + '_', relaId: 'pid'}
+                ]);
+            }
+            this.pos.loadDatas(posData);
+            this.pos.calculateAll(function (p) {
+                p.pre_gather_qty = helper.add(p.pre_contract_qty, p.pre_qc_qty);
+                for (const role of validRole) {
+                    const prefix = 'r' + role.flowOrder + '_';
+                    p[prefix + 'gather_qty'] = helper.add(p[prefix + 'contract_qty'], p[prefix + 'qc_qty']);
+                }
+
+            });
+
+            return this.pos.getDatas();
+        }
+
         async getStagePayData(tid, sid, fields) {
             await this.ctx.service.tender.checkTender(tid);
             await this.ctx.service.stage.checkStage(sid);
@@ -534,6 +610,13 @@ module.exports = app => {
                 const payCalculator = new PayCalculator(this.ctx, this.ctx.stage, this.ctx.tender.info);
                 await payCalculator.calculateAll(dealPay);
             }
+            if (this._checkFieldsExist(fields, ['start_stage_order']) && this.ctx.stage.status !== audit.stage.status.checked) {
+                for (const dp of dealPay) {
+                    if (!dp.start_stage_order || dp.start_stage_order === this.ctx.stage.order) {
+                        dp.start_stage_order = this.ctx.helper.checkZero(dp.tp) ? null : this.ctx.stage.order;
+                    }
+                }
+            }
 
             if (this._checkFieldsExistReg(fields, 'r[0-9]+_tp')) {
                 const validRole = this._getStageValidRole();
@@ -578,7 +661,7 @@ module.exports = app => {
             const self = this;
             try {
                 const decimal = this.ctx.tender.info.decimal, ctx = this.ctx;
-                const change = await this.ctx.service.change.getListByStatus(tid, 3);
+                const change = await this.ctx.service.change.getAllCheckedChanges(tid);
                 for (const c of change) {
                     const types = ctx.helper._.map(c.type.split(','), function (t) {
                         return self._getChangeConstName(changeConst.type, ctx.helper._.toInteger(t));
@@ -595,7 +678,6 @@ module.exports = app => {
                 }
                 const changeBills = await this.ctx.service.changeAuditList.getChangeAuditBills(tid);
                 for (const d of changeBills) {
-                    //const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, d.unit);
                     d.o_qty = d.oamount;
                     d.o_tp = this.ctx.helper.mul(d.o_qty, d.unit_price, decimal.tp);
                     d.c_qty = d.camount;

+ 19 - 0
app/service/rpt_custom_define.js

@@ -28,6 +28,25 @@ module.exports = app => {
             }
             return data;
         }
+
+        async addInitialStageData(stage, preStage, transaction) {
+            if (!stage || !preStage) {
+                throw '标段数据有误';
+            }
+            const preDatas = await this.getAllDataByCondition({
+                where: {sid: preStage.id}
+            });
+            if (preDatas.length > 0) {
+                for (const pd of preDatas) {
+                    delete pd.id;
+                    pd.sid = stage.id;
+                }
+                const result = await transaction.insert(this.tableName, preDatas);
+                return result.affectedRows === preDatas.length;
+            } else {
+                return true;
+            }
+        }
     }
 
     return RptCustomDefine;

+ 4 - 0
app/service/stage.js

@@ -275,6 +275,10 @@ module.exports = app => {
                     const otherResult = await this.ctx.service.stageOther.addInitialStageData(newStage, preStage, transaction);
                     if (!otherResult) throw '初始化其他台账数据失败';
                 }
+                // 新增期拷贝报表相关配置
+                if (preStage) {
+                    const rptResult = await this.ctx.service.rptCustomDefine.addInitialStageData(newStage, preStage, transaction);
+                }
 
                 await transaction.commit();
                 return newStage;

+ 0 - 1
app/service/stage_jgcl.js

@@ -227,7 +227,6 @@ module.exports = app => {
             } else {
                 return true;
             }
-
         }
     }
 

+ 8 - 3
app/service/stage_pay.js

@@ -58,7 +58,8 @@ module.exports = app => {
          */
         async getAuditorStageData(sid, times, order) {
             const sql = 'SELECT SP.*,' +
-                '    P.`csorder`, P.`cstimes`, P.`csaorder`, P.`order`, P.uid, P.minus, P.ptype, P.sprice, P.sexpr, P.rprice, P.rexpr, P.is_yf, P.dl_type, P.dl_count, P.dl_tp_type, P.dl_tp, P.name as pName ' +
+                '    P.`csorder`, P.`cstimes`, P.`csaorder`, P.`order`, P.uid, P.minus, P.ptype, P.sprice, P.sexpr,' +
+                '    P.rprice, P.rexpr, P.is_yf, P.dl_type, P.dl_count, P.dl_tp_type, P.dl_tp, P.name as pName ' +
                 '  FROM ?? As SP, ?? As P ' +
                 '  WHERE SP.`sid` = ? AND SP.`stimes` = ? AND SP.`sorder` = ? AND SP.`pid` = P.`id` AND P.`valid`' +
                 '  ORDER BY P.`order`';
@@ -102,6 +103,7 @@ module.exports = app => {
                         pre_tp: pp.end_tp,
                         pre_used: pp.pre_used || !this.ctx.helper.checkZero(pp.tp),
                         pre_finish: pp.pre_finish || (pp.rprice ? pp.end_tp === pp.rprice : false),
+                        start_stage_order: pp.start_stage_order,
                     });
                 }
             } else {
@@ -223,6 +225,9 @@ module.exports = app => {
                     id: sp.id,
                     tp: sp.tp,
                     end_tp: sp.end_tp,
+                    start_stage_order: sp.start_stage_order && sp.start_stage_order < stage.order
+                        ? sp.start_stage_order
+                        : (this.ctx.helper.checkZero(sp.tp) ? null : stage.order),
                 });
                 if (stage.order === 1 || sp.csorder >= stage.order) {
                     srUpdate.push({
@@ -263,8 +268,8 @@ module.exports = app => {
             if (!stage || !transaction || !times || order === undefined) {
                 throw '数据错误';
             }
-            const sql = 'INSERT INTO ?? (`tid`, `sid`, `pid`, `stimes`, `sorder`, `name`, `tp`, `expr`, `pause`, `attachment`, `pre_tp`, `end_tp`) ' +
-                        '  SELECT SP.`tid`, SP.`sid`, SP.`pid`, ?, ?, SP.name, SP.`tp`, SP.`expr`, SP.`pause`, SP.`attachment`, SP.`pre_tp`, SP.`end_tp` ' +
+            const sql = 'INSERT INTO ?? (`tid`, `sid`, `pid`, `stimes`, `sorder`, `name`, `tp`, `expr`, `pause`, `attachment`, `pre_tp`, `end_tp`, `pre_finish`, `start_stage_order`) ' +
+                        '  SELECT SP.`tid`, SP.`sid`, SP.`pid`, ?, ?, SP.name, SP.`tp`, SP.`expr`, SP.`pause`, SP.`attachment`, SP.`pre_tp`, SP.`end_tp`, SP.`pre_finish`, SP.`start_stage_order` ' +
                         '  FROM ?? As SP, ?? As P ' +
                         '  WHERE SP.`sid` = ? AND SP.`stimes` = ? AND SP.`sorder` = ? And SP.`pid` = P.`id` And P.`valid`';
             const sqlParam = [this.tableName, times, order, this.tableName, this.ctx.service.pay.tableName,

+ 2 - 0
app/view/report/rpt_all_popup.ejs

@@ -259,6 +259,8 @@
                     <tbody id="audit-select-list">
                     </tbody>
                 </table>
+                <div id="audit-select-hint" class="text-danger">
+                </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>

+ 122 - 2
builder_report_index_define.js

@@ -22,6 +22,7 @@ const tag = {
     tp: {type: 'tp'},
     up: {type: 'up'},
 };
+// 其他台账
 const stage_jgcl = {
     name: '期-甲供材料(mem_stage_jgcl)',
     remark: '',
@@ -101,6 +102,7 @@ const stage_other = {
         {name: '截止上期-金额', field: 'pre_tp', type: dataType.currency, tag: {type: 'tp'}},
     ]
 };
+// 变更令
 const change = {
     name: '变更令(mem_change)',
     remark: '',
@@ -184,6 +186,124 @@ const changeBills = {
 
     ]
 };
+// 期 - 计量单元
+const stage_pos = {
+    name: '期-计量单元(mem_stage_pos)',
+    remark: '',
+    id: 34,
+    key: 'stage_pos',
+    prefix: '期-计量单元',
+    cols: [
+        {name: 'id', field: 'id', type: dataType.str},
+        {name: '所属标段id', field: 'tid', type: dataType.int},
+        {name: '所属清单id', field: 'lid', type: dataType.str},
+        {name: '名称', field: 'name', type: dataType.str},
+        {name: '位置', field: 'position', type: dataType.str},
+        {name: '施工复核-数量', field: 'sgfh_qty', type: dataType.currency},
+        {name: '其他错漏-数量', field: 'qtcl_qty', type: dataType.currency},
+        {name: '设计错漏-数量', field: 'sjcl_qty', type: dataType.currency},
+        {name: '台账-数量', field: 'quantity', type: dataType.currency},
+        {name: '图号', field: 'drawing_code', type: dataType.str},
+        {name: '排序', field: 'p_order', type: dataType.str},
+        {name: '本期-合同计量-数量', field: 'contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量', field: 'qc_qty', type: dataType.currency},
+        {name: '本期-数量变更-变更令', field: 'qc_bgl_code', type: dataType.str},
+        {name: '本期-完成计量-数量', field: 'gather_qty', type: dataType.currency},
+        {name: '本期批注', field: 'postil', type: dataType.str},
+        {name: '截止上期-合同计量-数量', field: 'pre_contract_qty', type: dataType.currency},
+        {name: '截止上期-数量变更-数量', field: 'pre_qc_qty', type: dataType.currency},
+        {name: '截止上期-完成计量-数量', field: 'pre_gather_qty', type: dataType.currency},
+        {name: '截止本期-合同计量-数量', field: 'end_contract_qty', type: dataType.currency},
+        {name: '截止本期-数量变更-数量', field: 'end_qc_qty', type: dataType.currency},
+        {name: '截止本期-完成计量-数量', field: 'end_gather_qty', type: dataType.currency},
+        {name: '截止本期-完成率', field: 'final_ratio', type: dataType.currency},
+    ],
+};
+const stage_pos_compare = {
+    name: '期-计量单元-全参与人(mem_stage_pos_compare)',
+    remark: '',
+    id: 35,
+    key: 'stage_pos_compare',
+    prefix: '期-计量单元-全参与人',
+    cols: [
+        {name: 'id', field: 'id', type: dataType.str},
+        {name: '所属标段id', field: 'tid', type: dataType.int},
+        {name: '所属清单id', field: 'lid', type: dataType.str},
+        {name: '名称', field: 'name', type: dataType.str},
+        {name: '位置', field: 'position', type: dataType.str},
+        {name: '施工复核-数量', field: 'sgfh_qty', type: dataType.currency},
+        {name: '其他错漏-数量', field: 'qtcl_qty', type: dataType.currency},
+        {name: '设计错漏-数量', field: 'sjcl_qty', type: dataType.currency},
+        {name: '台账-数量', field: 'quantity', type: dataType.currency},
+        {name: '图号', field: 'drawing_code', type: dataType.str},
+        {name: '排序', field: 'p_order', type: dataType.str},
+        {name: '截止上期-合同计量-数量', field: 'pre_contract_qty', type: dataType.currency},
+        {name: '截止上期-数量变更-数量', field: 'pre_qc_qty', type: dataType.currency},
+        {name: '截止上期-完成计量-数量', field: 'pre_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_0', field: 'r0_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_0', field: 'r0_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_0', field: 'r0_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_1', field: 'r1_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_1', field: 'r1_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_1', field: 'r1_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_2', field: 'r2_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_2', field: 'r2_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_2', field: 'r2_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_3', field: 'r3_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_3', field: 'r3_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_3', field: 'r3_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_4', field: 'r4_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_4', field: 'r4_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_4', field: 'r4_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_5', field: 'r5_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_5', field: 'r5_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_5', field: 'r5_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_6', field: 'r6_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_6', field: 'r6_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_6', field: 'r6_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_7', field: 'r7_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_7', field: 'r7_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_7', field: 'r7_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_8', field: 'r8_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_8', field: 'r8_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_8', field: 'r8_gather_qty', type: dataType.currency},
+        {name: '本期-合同计量-数量_9', field: 'r9_contract_qty', type: dataType.currency},
+        {name: '本期-数量变更-数量_9', field: 'r9_qc_qty', type: dataType.currency},
+        {name: '本期-完成计量-数量_9', field: 'r9_gather_qty', type: dataType.currency},
+    ],
+};
+
+// 期 - 合同支付
+const stage_pay = {
+    Name: '期-合同支付-数据(mem_stage_pay)',
+    remark: '',
+    id: 27,
+    key: 'mem_stage_pay',
+    prefix: '期-合同支付',
+    cols: [
+        {name: '名称', field: 'name', type: dataType.str},
+        {name: '计算公式', field: 'expr', type: dataType.str},
+        {name: '金额', field: 'tp', type: dataType.currency},
+        {name: '截止上期-金额', field: 'pre_tp', type: dataType.currency},
+        {name: '截止上期-金额', field: 'end_tp', type: dataType.currency},
+        {name: '排序', field: 'order', type: dataType.int},
+        {name: '是否扣款项', field: 'minus', type: dataType.int},
+        {name: '支付类型', field: 'ptype', type: dataType.int},
+        {name: '起扣金额', field: 'sprice', type: dataType.currency},
+        {name: '扣款限额', field: 'rprice', type: dataType.currency},
+        {name: '流程-本期-金额_0', field: 'r0_tp', type: dataType.currency},
+        {name: '流程-本期-金额_1', field: 'r1_tp', type: dataType.currency},
+        {name: '流程-本期-金额_2', field: 'r2_tp', type: dataType.currency},
+        {name: '流程-本期-金额_3', field: 'r3_tp', type: dataType.currency},
+        {name: '流程-本期-金额_4', field: 'r4_tp', type: dataType.currency},
+        {name: '流程-本期-金额_5', field: 'r5_tp', type: dataType.currency},
+        {name: '流程-本期-金额_6', field: 'r6_tp', type: dataType.currency},
+        {name: '流程-本期-金额_7', field: 'r7_tp', type: dataType.currency},
+        {name: '流程-本期-金额_8', field: 'r8_tp', type: dataType.currency},
+        {name: '流程-本期-金额_9', field: 'r9_tp', type: dataType.currency},
+        {name: '第几期开始计量', field: 'start_stage_order', type: dataType.int},
+    ],
+};
 
 const recursiveMkdirSync = async function (pathName) {
     if (!fs.existsSync(pathName)) {
@@ -268,10 +388,10 @@ const exportTableDefine = async function (define) {
     for (const col of define.cols) {
         addFields(tableDefine, col.name, col.field, col.type, col.tag);
     }
-    await saveTableDefine(tableDefine, path.join(savePath, define.key + '.json'));
+    await saveTableDefine(tableDefine, path.join(savePath, define.key + '_define.json'));
 };
 
-const defines = [change, changeBills];
+const defines = [stage_pay];
 for (const d of defines) {
     exportTableDefine(d);
 }

+ 2 - 0
sql/update.sql

@@ -0,0 +1,2 @@
+ALTER TABLE `zh_stage_pay`
+ADD COLUMN `start_stage_order`  tinyint(4) NULL COMMENT '第几期开始计量' AFTER `pre_finish`;

+ 89 - 0
sql/update20200323.sql

@@ -0,0 +1,89 @@
+INSERT INTO `calculation`.`zh_permission` (`id`, `name`, `controller`, `action`, `pid`, `icon_class`, `create_time`, `isshow`) VALUES ('66', '合同支付', 'project', 'dealpay', '38', '', NULL, '1');
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for zh_stage_jgcl
+-- ----------------------------
+DROP TABLE IF EXISTS `zh_stage_jgcl`;
+CREATE TABLE `zh_stage_jgcl` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `uuid` varchar(50) CHARACTER SET ascii NOT NULL COMMENT '材料id(uuid)',
+  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
+  `unit` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '单位',
+  `unit_price` decimal(24,8) DEFAULT NULL COMMENT '单价',
+  `arrive_qty` decimal(24,8) DEFAULT NULL COMMENT '本期 - 到场 - 数量',
+  `arrive_tp` decimal(24,8) DEFAULT NULL COMMENT '本期 - 到场 - 金额',
+  `deduct_qty` decimal(24,8) DEFAULT NULL COMMENT '本期 - 扣回 - 数量',
+  `deduct_tp` decimal(24,8) DEFAULT NULL COMMENT '本期 - 扣回 - 金额',
+  `source` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '材料来源',
+  `bills_code` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '单据号',
+  `check_code` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '检验单编号',
+  `memo` text CHARACTER SET utf8 COMMENT '备注',
+  `add_uid` int(11) NOT NULL COMMENT '新增人id',
+  `add_sid` int(11) NOT NULL COMMENT '新增期id',
+  `sid` int(11) NOT NULL COMMENT '所属期id',
+  `shistory` text COLLATE utf8_unicode_ci COMMENT '所属期-第几轮',
+  `order` int(11) NOT NULL COMMENT '排序字段',
+  `pre_used` tinyint(1) DEFAULT NULL COMMENT '是否计量过',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=132 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+-- ----------------------------
+-- Table structure for zh_stage_bonus
+-- ----------------------------
+DROP TABLE IF EXISTS `zh_stage_bonus`;
+CREATE TABLE `zh_stage_bonus` (
+  `id` varchar(50) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT '主键id(uuid)',
+  `tid` int(11) NOT NULL COMMENT '标段id',
+  `sid` int(11) NOT NULL COMMENT '期id',
+  `sorder` tinyint(4) NOT NULL COMMENT '第几期',
+  `uid` int(11) NOT NULL COMMENT '新增人',
+  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT '名称',
+  `tp` decimal(24,8) DEFAULT NULL COMMENT '金额',
+  `code` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
+  `proof` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '依据材料证明',
+  `create_time` datetime(4) DEFAULT NULL COMMENT '创建时间',
+  `real_time` datetime(4) DEFAULT NULL COMMENT '实际时间-用户可修改',
+  `memo` text CHARACTER SET utf8 COMMENT '备注',
+  `shistory` text CHARACTER SET utf8 COMMENT '历史记录',
+  `order` int(4) DEFAULT NULL COMMENT '排序字段',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+-- ----------------------------
+-- Table structure for zh_stage_other
+-- ----------------------------
+DROP TABLE IF EXISTS `zh_stage_other`;
+CREATE TABLE `zh_stage_other` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `uuid` varchar(50) CHARACTER SET ascii NOT NULL COMMENT 'uuid',
+  `tid` int(11) NOT NULL COMMENT '标段id',
+  `sid` int(11) NOT NULL COMMENT '所属期id',
+  `sorder` tinyint(4) NOT NULL COMMENT '所属第几期',
+  `add_sid` int(11) NOT NULL COMMENT '新增期',
+  `add_uid` int(11) NOT NULL COMMENT '新增人',
+  `add_time` datetime(4) NOT NULL COMMENT '新建时间',
+  `name` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT '名称',
+  `total_price` decimal(24,8) DEFAULT NULL COMMENT '金额',
+  `tp` decimal(24,8) DEFAULT NULL COMMENT '本期 - 金额',
+  `real_time` datetime(4) DEFAULT NULL COMMENT '时间',
+  `memo` text CHARACTER SET utf8 COMMENT '备注',
+  `order` int(11) DEFAULT NULL COMMENT '排序',
+  `shistory` text COLLATE utf8_unicode_ci COMMENT '本期记录',
+  `pre_used` tinyint(1) DEFAULT NULL COMMENT '是否往期已用',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+-- ----------------------------
+-- Table structure for zh_rpt_custom_define
+-- ----------------------------
+DROP TABLE IF EXISTS `zh_rpt_custom_define`;
+CREATE TABLE `zh_rpt_custom_define` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `tid` int(11) NOT NULL COMMENT '标段id',
+  `sid` int(11) NOT NULL COMMENT '期id',
+  `rid` int(11) NOT NULL COMMENT '报表id',
+  `audit_select` text COLLATE utf8_unicode_ci COMMENT '用户定制信息',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

+ 15 - 11
test/app/service/report_memory_temp.test.js

@@ -19,25 +19,29 @@ describe('test/app/service/report_memory.test.js', () => {
         const ctx = app.mockContext();
         savePath = path.join(ctx.app.baseDir,'report_temp');
         const postData = {
-            account: 'zengpeiwen',
-            project: 'P1201',
-            project_password: '123456',
+            account: '734406061@qq.com',
+            project: 'T201711273363',
+            project_password: 'mai654321',
         };
+        // const postData = {
+        //     account: 'chente',
+        //     project: 'T201711273363',
+        //     project_password: '123456',
+        // };
         ctx.session = {};
         const loginResult = yield ctx.service.projectAccount.accountLogin(postData, 2);
         assert(loginResult);
         mockData.session = ctx.session;
     });
-    it('test mem_change_bills && mem_change ', function* () {
+    // 期部位明细数据
+    it('test getStagePos', function* () {
         const ctx = app.mockContext(mockData);
 
-        const change = yield ctx.service.reportMemory.getChangeData(2046);
-        if (change instanceof Array) {
-            yield ctx.helper.saveBufferFile(JSON.stringify(change, '', '\t'), path.join(savePath, 'mem_change.json'));
-        }
-        const data = yield ctx.service.reportMemory.getChangeBillsData(2046);
-        if (data instanceof Array) {
-            yield ctx.helper.saveBufferFile(JSON.stringify(data, '', '\t'), path.join(savePath, 'mem_change_bills.json'));
+        // test12 - 第6期
+        const stage = yield ctx.service.stage.getDataByCondition({tid: 2155, order: 2});
+        const mainData = yield ctx.service.reportMemory.getStagePayData(12, stage.id, ['start_stage_order']);
+        if (mainData instanceof Array) {
+            yield ctx.helper.saveBufferFile(JSON.stringify(mainData,"","\t"), path.join(savePath, 'mem_stage_pay.json'));
         }
     });
 });