Bladeren bron

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

TonyKang 5 jaren geleden
bovenliggende
commit
e19f7adac9

+ 28 - 0
app/controller/material_controller.js

@@ -232,6 +232,34 @@ module.exports = app => {
         }
 
         /**
+         * 调差清单页面 (Get)
+         * @param {Object} ctx - egg全局变量
+         * @returns {Promise<void>}
+         */
+        async list(ctx) {
+            try {
+                await this._getMaterialAuditViewData(ctx);
+                const renderData = await this._getDefaultRenderData(ctx);
+                // 取所有工料表
+                renderData.materialBillsData = await ctx.service.materialBills.getAllDataByCondition({ where: { tid: ctx.tender.id } });
+                // 取所有已被调用的工料清单表
+                renderData.materialListData = await ctx.service.materialList.getAllDataByCondition({ where: { tid: ctx.tender.id } });
+                renderData.materialType = JSON.stringify(materialConst);
+                renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.material.list);
+                // 获取清单数据
+                renderData.ledger = await ctx.service.ledger.getData(ctx.tender.id);
+                renderData.pos = await ctx.service.pos.getPosData({ tid: ctx.tender.id });
+                // 获取所选期数据并合并相加同类清单项
+                renderData.curLedgerData = await ctx.service.stageBills.getStagesData(ctx.tender.id, ctx.material.stage_id);
+                renderData.curPosData = await ctx.service.stagePos.getStagesData(ctx.tender.id, ctx.material.stage_id);
+                await this.layout('material/list.ejs', renderData);
+            } catch (err) {
+                this.log(err);
+                ctx.redirect('/tender/' + ctx.tender.id + '/measure/material');
+            }
+        }
+
+        /**
          * 调差工料 - 编辑工料项 (Ajax)
          * @param ctx
          * @returns {Promise<void>}

+ 29 - 26
app/controller/revise_controller.js

@@ -277,25 +277,27 @@ module.exports = app => {
             // 台账只读、使用数据
             renderData.readOnly = false;
             const lastStage = await ctx.service.stage.getLastestStage(ctx.tender.id, true);
-            if (lastStage.status === audit.stage.status.checked) {
-                const usedPreBills = await ctx.service.stageBillsFinal.getUsedBills(ctx.tender.id, lastStage.order);
-                for (const b of renderData.reviseBills) {
-                    b.used = usedPreBills.indexOf(b.id) >= 0;
-                }
-                const usedPrePos = await ctx.service.stagePosFinal.getUsedPos(ctx.tender.id, lastStage.order);
-                for (const p of renderData.revisePos) {
-                    p.used = usedPrePos.indexOf(p.id) >= 0;
-                }
-            } else {
-                const usedPreBills = lastStage.order > 1 ? await ctx.service.stageBillsFinal.getUsedBills(ctx.tender.id, lastStage.order - 1) : [];
-                const usedCurBills = await ctx.service.stageBills.getStageUsedBills(ctx.tender.id, lastStage.id);
-                for (const b of renderData.reviseBills) {
-                    b.used = usedPreBills.indexOf(b.id) >= 0 || usedCurBills.indexOf(b.id) >= 0;
-                }
-                const usedPrePos = lastStage.order > 1 ? await ctx.service.stagePosFinal.getUsedPos(ctx.tender.id, lastStage.order - 1) : [];
-                const usedCurPos = await ctx.service.stagePos.getStageUsedPos(ctx.tender.id, lastStage.id);
-                for (const p of renderData.revisePos) {
-                    p.used = usedPrePos.indexOf(p.id) >= 0 || usedCurPos.indexOf(p.id) >= 0;
+            if (lastStage) {
+                if (lastStage.status === audit.stage.status.checked) {
+                    const usedPreBills = await ctx.service.stageBillsFinal.getUsedBills(ctx.tender.id, lastStage.order);
+                    for (const b of renderData.reviseBills) {
+                        b.used = usedPreBills.indexOf(b.id) >= 0;
+                    }
+                    const usedPrePos = await ctx.service.stagePosFinal.getUsedPos(ctx.tender.id, lastStage.order);
+                    for (const p of renderData.revisePos) {
+                        p.used = usedPrePos.indexOf(p.id) >= 0;
+                    }
+                } else {
+                    const usedPreBills = lastStage.order > 1 ? await ctx.service.stageBillsFinal.getUsedBills(ctx.tender.id, lastStage.order - 1) : [];
+                    const usedCurBills = await ctx.service.stageBills.getStageUsedBills(ctx.tender.id, lastStage.id);
+                    for (const b of renderData.reviseBills) {
+                        b.used = usedPreBills.indexOf(b.id) >= 0 || usedCurBills.indexOf(b.id) >= 0;
+                    }
+                    const usedPrePos = lastStage.order > 1 ? await ctx.service.stagePosFinal.getUsedPos(ctx.tender.id, lastStage.order - 1) : [];
+                    const usedCurPos = await ctx.service.stagePos.getStageUsedPos(ctx.tender.id, lastStage.id);
+                    for (const p of renderData.revisePos) {
+                        p.used = usedPrePos.indexOf(p.id) >= 0 || usedCurPos.indexOf(p.id) >= 0;
+                    }
                 }
             }
             // 修订历史
@@ -411,7 +413,7 @@ module.exports = app => {
             if ((isNaN(data.id) || data.id <= 0) ||
                 (!data.tid && data.tid <= 0) ||
                 (!data.block || data.block.length <= 0)) throw '参数错误';
-            return await ctx.service.revise.pasteBlock(data.tid, data.id, data.block);
+            return await this.ctx.service.revise.pasteBlock(data.tid, data.id, data.block);
         }
         async _addStd(revise, data) {
             if ((isNaN(data.id) || data.id <= 0) || !data.stdType || !data.stdNode) throw '参数错误';
@@ -420,12 +422,12 @@ module.exports = app => {
             let stdLib, addType;
             switch (data.stdType) {
                 case 'xmj':
-                    stdLib = ctx.service.stdXmj;
+                    stdLib = this.ctx.service.stdXmj;
                     addType = stdDataAddType.withParent;
                     break;
                 case 'gcl':
-                    stdLib = ctx.service.stdGcl;
-                    const selectNode = await ctx.service.reviseBills.getDataByKid(ctx.tender.id, data.id);
+                    stdLib = this.ctx.service.stdGcl;
+                    const selectNode = await this.ctx.service.reviseBills.getDataByKid(revise.tid, data.id);
                     if (selectNode.b_code) {
                         addType = stdDataAddType.next;
                     } else {
@@ -438,17 +440,18 @@ module.exports = app => {
             const stdData = await stdLib.getDataByDataId(data.stdLibId, data.stdNode);
             switch (addType) {
                 case stdDataAddType.child:
-                    return await ctx.service.reviseBills.addStdNodeAsChild(ctx.tender.id, data.id, stdData, ctx.revise.id);
+                    return await this.ctx.service.reviseBills.addStdNodeAsChild(revise.tid, data.id, stdData, revise.id);
                     break;
                 case stdDataAddType.next:
-                    return await ctx.service.reviseBills.addStdNode(ctx.tender.id, data.id, stdData, ctx.revise.id);
+                    return await this.ctx.service.reviseBills.addStdNode(revise.tid, data.id, stdData, revise.id);
                 case stdDataAddType.withParent:
-                    return await ctx.service.reviseBills.addStdNodeWithParent(ctx.tender.id, stdData, stdLib, ctx.revise.id);
+                    return await this.ctx.service.reviseBills.addStdNodeWithParent(revise.tid, stdData, stdLib, revise.id);
                 default:
                     throw '未知添加方式';
             }
         }
         async _addDeal(revise, data) {
+            console.log(data);
             if (!data.type || !data.dealBills) throw '数据错误';
             if (data.type === 'child') {
                 return await this.ctx.service.reviseBills.addChild(revise.tid, data.id, data.dealBills, revise.id);

+ 4 - 0
app/lib/pay_calc.js

@@ -100,9 +100,13 @@ class PayCalculate {
                 if (p.csaorder === order) {
                     if (!p.sprice && p.sexpr && p.sexpr !== '') {
                         p.sprice = this.ctx.helper.round(this.calculateExpr(p.sexpr), this.decimal);
+                    } else if (p.sprice && !p.sexpr) {
+                        p.sprice = this.ctx.helper.round(p.sprice, this.decimal);
                     }
                     if (!p.rprice && p.rexpr && p.rexpr !== '') {
                         p.rprice = this.ctx.helper.round(this.calculateExpr(p.rexpr), this.decimal);
+                    } else if (p.rprice && !p.rexpr) {
+                        p.rprice = this.ctx.helper.round(p.rprice, this.decimal);
                     }
                 }
             }

+ 1 - 0
app/middleware/stage_check.js

@@ -96,6 +96,7 @@ module.exports = options => {
             } else { // 其他不可见
                 throw '您无权查看该数据';
             }
+            console.log(stage.readOnly);
 
             const lastRevise = yield this.service.ledgerRevise.getLastestRevise(this.tender.id);
             stage.revising = (lastRevise && lastRevise.status !== reviseStatus.checked) || false;

+ 1 - 0
app/public/js/gcl_gather.js

@@ -274,6 +274,7 @@ const gclGatherModel = (function () {
             dx.gcl_id = node.id;
             if (d.name !== node.name) {
                 dx.bwmx = d.name;
+                dx.mx_id = d.id;
             }
             if (d.drawing_code) {
                 dx.drawaing_code = d.drawing_code;

+ 1 - 1
app/public/js/ledger.js

@@ -1914,10 +1914,10 @@ $(document).ready(function() {
     });
     // 显示层次
     (function (select, sheet) {
-        if (!sheet.zh_tree) return;
         $(select).click(function () {
             const tag = $(this).attr('tag');
             const tree = sheet.zh_tree;
+            if (!tree) return;
             switch (tag) {
                 case "1":
                 case "2":

+ 146 - 0
app/public/js/material_list.js

@@ -0,0 +1,146 @@
+'use strict';
+
+/**
+ * 材料调差 - 调差清单
+ *
+ * @author EllisRan
+ * @date 2019/10/25
+ * @version
+ */
+
+$(document).ready(() => {
+    autoFlashHeight();
+    // 清单table
+    const ledgerSpread = SpreadJsObj.createNewSpread($('#ledger-spread')[0]);
+    const ledgerSpreadSetting = {
+        cols: [
+            {title: '清单编号', colSpan: '1', rowSpan: '2', field: 'b_code', hAlign: 0, width: 150, formatter: '@'},
+            {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 250, formatter: '@'},
+            {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 120, formatter: '@'},
+            {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 120, type: 'Number'},
+            {title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 120, type: 'Number'},
+            {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 120, type: 'Number'},
+            {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'total_qty', hAlign: 2, width: 120, type: 'Number', getValue: 'getValue.qty'},
+        ],
+        emptyRows: 0,
+        headRows: 2,
+        headRowHeight: [32, 32],
+        defaultRowHeight: 30,
+        headerFont: '10pt 微软雅黑',
+        readOnly: true,
+        font: '10pt 微软雅黑',
+    };
+
+    const ledgerCol = {
+        getValue: {
+            qty: function (data) {
+                return ZhCalc.add(data.contract_qty, data.qc_qty);
+            }
+        }
+    };
+    // 解析清单汇总数据
+    gclGatherModel.loadLedgerData(ledger, curLedgerData);
+    gclGatherModel.loadPosData(pos, curPosData);
+    const gclGatherData = gclGatherModel.gatherGclData();
+    // 获取项目节数据
+    function loadLeafXmjData(iGclRow) {
+        const gcl = gclGatherData[iGclRow];
+        if (gcl) {
+            SpreadJsObj.loadSheetData(leafXmjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gcl.leafXmjs);
+        } else {
+            SpreadJsObj.loadSheetData(leafXmjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, []);
+        }
+    }
+    SpreadJsObj.initSpreadSettingEvents(ledgerSpreadSetting, ledgerCol);
+    SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), ledgerSpreadSetting);
+
+    // 项目明细table
+    const leafXmjSpread = SpreadJsObj.createNewSpread($('#leaf-xmj-spread')[0]);
+    const leafXmjSpreadSetting = {
+        cols: [
+            {title: '项目节|编号', colSpan: '2|1', rowSpan: '1|1', field: 'code', hAlign: 0, width: 80, formatter: '@'},
+            {title: '|项目节名称', colSpan: '|1', rowSpan: '|1', field: 'jldy', hAlign: 0, width: 100, formatter: '@'},
+            {title: '部位明细|部位明细', colSpan: '2|1', rowSpan: '1|1', field: 'bwmx', hAlign: 0, width: 100, formatter: '@'},
+            {title: '|复核数量', colSpan: '|1', rowSpan: '|1', field: 'quantity', hAlign: 0, width: 80, type: 'Number'},
+            {title: '部位信息|单位工程', colSpan: '3|1', rowSpan: '1|1', field: 'dwgc', hAlign: 0, width: 100, formatter: '@'},
+            {title: '|分部工程', colSpan: '|1', rowSpan: '|1', field: 'fbgc', hAlign: 0, width: 100, formatter: '@'},
+            {title: '|分项工程', colSpan: '|1', rowSpan: '|1', field: 'fxgc', hAlign: 0, width: 180, formatter: '@'},
+            {title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 80, type: 'Number'},
+            {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'total_qty', hAlign: 2, width: 60, type: 'Number', getValue: 'getValue.qty'},
+            {title: '本期价差', colSpan: '1', rowSpan: '2', field: 'jijia', hAlign: 2, width: 80, type: 'Number'},
+        ],
+        emptyRows: 0,
+        headRows: 2,
+        headRowHeight: [32, 32],
+        defaultRowHeight: 30,
+        headerFont: '10pt 微软雅黑',
+        readOnly: true,
+        font: '10pt 微软雅黑',
+    };
+    const leafXmjCol = {
+        getValue: {
+            qty: function (data) {
+                return ZhCalc.add(data.contract_qty, data.qc_qty);
+            }
+        }
+    };
+    SpreadJsObj.initSpreadSettingEvents(leafXmjSpreadSetting, leafXmjCol);
+    SpreadJsObj.initSheet(leafXmjSpread.getActiveSheet(), leafXmjSpreadSetting);
+    // 加载清单数据
+    SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gclGatherData);
+    loadLeafXmjData(0);
+    SpreadJsObj.forbiddenSpreadContextMenu('#ledger-spread', ledgerSpread);
+
+    // 调差清单工料table
+    const materialSpread = SpreadJsObj.createNewSpread($('#material-spread')[0]);
+    const materialSpreadSetting = {
+        cols: [
+            {title: '清单调差工料|编号', colSpan: '4|1', rowSpan: '1|1', field: 'code', hAlign: 0, width: 80, formatter: '@'},
+            {title: '|名称', colSpan: '|1', rowSpan: '|1', field: 'name', hAlign: 0, width: 100, formatter: '@'},
+            {title: '|单位', colSpan: '|1', rowSpan: '|1', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
+            {title: '|kg数量', colSpan: '1', rowSpan: '|1', field: 'num', hAlign: 2, width: 60, type: 'Number'},
+        ],
+        emptyRows: 0,
+        headRows: 2,
+        headRowHeight: [32, 32],
+        defaultRowHeight: 30,
+        headerFont: '10pt 微软雅黑',
+        readOnly: true,
+        font: '10pt 微软雅黑',
+    };
+    SpreadJsObj.initSheet(materialSpread.getActiveSheet(), materialSpreadSetting);
+
+    if (!readOnly) {
+    } else {
+        SpreadJsObj.forbiddenSpreadContextMenu('#leaf-xmj-spread', leafXmjSpread);
+        SpreadJsObj.forbiddenSpreadContextMenu('#material-spread', materialSpread);
+    }
+
+    // 切换清单行,读取所属项目节数据
+    ledgerSpread.getActiveSheet().bind(spreadNS.Events.SelectionChanged, function (e, info) {
+        const iOldRow = info.oldSelections[0].row, iNewRow = info.newSelections[0].row;
+        if (iNewRow !== iOldRow) {
+            loadLeafXmjData(iNewRow);
+        }
+    });
+
+    $.subMenu({
+        menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
+        toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
+        //key: 'stage.compare.memu.1.0.0',
+        callback: function (info) {
+            if (info.mini) {
+                $('.panel-title').addClass('fluid');
+                $('#sub-menu').removeClass('panel-sidebar');
+            } else {
+                $('.panel-title').removeClass('fluid');
+                $('#sub-menu').addClass('panel-sidebar');
+            }
+            autoFlashHeight();
+            ledgerSpread.refresh();
+            leafXmjSpread.refresh();
+            materialSpread.refresh();
+        }
+    });
+});

+ 6 - 1
app/public/js/revise.js

@@ -883,7 +883,7 @@ $(document).ready(() => {
             if (!readOnly) {
                 this.spread.bind(spreadNS.Events.CellDoubleClick, function (e, info) {
                     const dealSheet = info.sheet;
-                    const mainSheet = ledgerSpread.getActiveSheet();
+                    const mainSheet = billsSheet;
 
                     const dealBills = SpreadJsObj.getSelectObject(dealSheet);
                     if (!dealBills) { return; }
@@ -1240,6 +1240,11 @@ $(document).ready(() => {
                 searchLedger.spread.refresh();
             }
         }
+        else {// 收起工具栏
+            tab.removeClass('active');
+            tabPanel.removeClass('active');
+            showSideTools(tab.hasClass('active'));
+        }
         billsSpread.refresh();
         if (posSpread) {
             posSpread.refresh();

+ 5 - 0
app/public/js/revise_history.js

@@ -238,6 +238,11 @@ $(document).ready(() => {
                 searchLedger.spread.refresh();
             }
         }
+        else {// 收起工具栏
+            tab.removeClass('active');
+            tabPanel.removeClass('active');
+            showSideTools(tab.hasClass('active'));
+        }
         billsSpread.refresh();
         if (posSpread) {
             posSpread.refresh();

+ 33 - 12
app/public/js/stage_pay.js

@@ -112,7 +112,28 @@ $(document).ready(() => {
             {title: '截止上期金额',  colSpan: '1', rowSpan: '1', field: 'pre_tp', hAlign: 2, width: 100, readOnly: true},
             {title: '截止本期金额',  colSpan: '1', rowSpan: '1', field: 'end_tp', hAlign: 2, width: 100, readOnly: true},
             {title: '起扣金额',  colSpan: '1', rowSpan: '1', field: 'sprice', hAlign: 2, width: 100, readOnly: 'readOnly.sprice', /*cellType: 'tip', getTip: function (data) {return data ? data.sexpr : '';}*/},
-            {title: '付(扣)款限额',  colSpan: '1', rowSpan: '1', field: 'rprice', hAlign: 2, width: 100, readOnly: 'readOnly.rprice', /*cellType: 'tip', getTip: function (data) {return data ? data.rexpr : '';}*/},
+            {
+                title: '付(扣)款限额',  colSpan: '1', rowSpan: '1', field: 'rprice', hAlign: 2, width: 100,
+                readOnly: 'readOnly.rprice', cellType: 'tip',
+                getTip: function (data) {
+                    if (data && (data.rexpr || data.rprice) && data.dl_type) {
+                        if (data.dl_type === 1) {
+                            return '计提期限为(当 计量期数 ≥ ' + data.dl_count + ')';
+                        } else if (data.dl_type === 2) {
+                            switch (data.dl_tp_type) {
+                                case 'contract':
+                                    return '计提期限为(累计合同计量 ≥ ' + data.dl_tp + ')';
+                                case 'qc':
+                                    return '计提期限为(累计变更计量 ≥ ' + data.dl_tp + ')';
+                                case 'gather':
+                                    return '计提期限为(累计完成计量 ≥ ' + data.dl_tp + ')';
+                            }
+                        }
+                    } else {
+                        return '';
+                    }
+                }
+             },
             {
                 title: '附件', colSpan: '1', rowSpan: '1', field: 'attachment', hAlign: 0, width: 60, readOnly: true, cellType: 'imageBtn',
                 normalImg: '#rela-file-icon', hoverImg: '#rela-file-hover', getValue: 'getValue.attachment'
@@ -405,12 +426,12 @@ $(document).ready(() => {
             if (!valid) return [valid, msg];
 
             if (payBase.isStarted(payNode)) {
-                if (payNode.pre_finish) return [false, '已达扣款限额,请勿修改'];
-                const value = expr ? payCalc.calculateExpr(expr) : num;
-                if (payNode.pre_tp && value < payNode.pre_tp) return [false, '截止上期已计量' + payNode.pre_tp + ',扣款限额请勿少于改值'];
-                data.rprice = num;
-                data.rexpr = expr;
-                return [true, ''];
+                // if (payNode.pre_finish) return [false, '已达扣款限额,请勿修改'];
+                // const value = expr ? payCalc.calculateExpr(expr) : num;
+                // if (payNode.pre_tp && value < payNode.pre_tp) return [false, '截止上期已计量' + payNode.pre_tp + ',扣款限额请勿少于改值'];
+                // data.rprice = num;
+                // data.rexpr = expr;
+                return [false, '已经开始使用,请勿修改扣款限额'];
             } else {
                 data.rprice = num;
                 data.rexpr = expr;
@@ -983,7 +1004,7 @@ $(document).ready(() => {
                 },
                 visible: function (key, opt) {
                     const select = SpreadJsObj.getSelectObject(paySpread.getActiveSheet());
-                    return !payBase.isSpecial(select) && !readOnly && !payBase.pause && payCol.menuVisible.pause(select);
+                    return !payBase.isSpecial(select) && !readOnly && !select.pause && payCol.menuVisible.pause(select);
                 },
             },
             'setDeadline': {
@@ -1008,7 +1029,7 @@ $(document).ready(() => {
                 icon: 'fa-chain-broken',
                 visible: function (key, opt) {
                     const select = SpreadJsObj.getSelectObject(paySpread.getActiveSheet());
-                    return !payBase.isSpecial(select) && select.is_yf && payCol.menuVisible.belongYF(select);
+                    return !payBase.isSpecial(select) && select.is_yf && payCol.menuVisible.belongYF(select) && !readOnly;
                 },
                 callback: function (key, opt) {
                     const select = SpreadJsObj.getSelectObject(paySpread.getActiveSheet());
@@ -1031,7 +1052,7 @@ $(document).ready(() => {
                 icon: 'fa-chain',
                 visible: function (key, opt) {
                     const select = SpreadJsObj.getSelectObject(paySpread.getActiveSheet());
-                    return !payBase.isSpecial(select) && !select.is_yf && payCol.menuVisible.belongYF(select);
+                    return !payBase.isSpecial(select) && !select.is_yf && payCol.menuVisible.belongYF(select) && !readOnly;
                 },
                 callback: function (key, opt) {
                     const select = SpreadJsObj.getSelectObject(paySpread.getActiveSheet());
@@ -1120,7 +1141,7 @@ $(document).ready(() => {
             formData.append('file[]', file);
         }
         // formData.append('size', sizes.join(','));
-        postDataWithFile('/tender/' + tender.id + '/measure/stage/' + tender.ledger_times + '/pay/upload/file', formData, function (data) {
+        postDataWithFile('/tender/' + tender.id + '/measure/stage/' + stage.order + '/pay/upload/file', formData, function (data) {
             if (select.attachment === null) {
                 select.attachment = data;
             } else {
@@ -1145,7 +1166,7 @@ $(document).ready(() => {
             index,
         };
         const select = SpreadJsObj.getSelectObject(paySpread.getActiveSheet());
-        postData('/tender/' + tender.id + '/measure/stage/' + tender.ledger_times + '/pay/delete/file', data, function (result) {
+        postData('/tender/' + tender.id + '/measure/stage/' + stage.order + '/pay/delete/file', data, function (result) {
             select.attachment.splice(index, 1);
             makeAttTable(select);
             const pay_index = dealPay.indexOf(select);

+ 4 - 2
app/router.js

@@ -159,7 +159,7 @@ module.exports = app => {
     app.post('/tender/:id/measure/stage/:order/pay/save', sessionAuth, tenderCheck, stageCheck, 'stageController.savePayData');
     app.post('/tender/:id/measure/stage/:order/pay/upload/file', sessionAuth, tenderCheck, stageCheck, 'stageController.payUploadFile');
     app.get('/tender/:id/measure/stage/:order/pay/download/file/:pid/:index', sessionAuth, 'stageController.payDownloadFile');
-    app.post('/tender/:id/measure/stage/:order/pay/delete/file', sessionAuth, 'stageController.payDeleteFile');
+    app.post('/tender/:id/measure/stage/:order/pay/delete/file', sessionAuth, tenderCheck, stageCheck, 'stageController.payDeleteFile');
     // 变更概况
     app.get('/tender/:id/measure/stage/:order/change', sessionAuth, tenderCheck, stageCheck, 'stageController.change');
     app.post('/tender/:id/measure/stage/:order/change/data', sessionAuth, tenderCheck, stageCheck, 'stageController.getChangeData');
@@ -213,7 +213,6 @@ module.exports = app => {
 
     // 材料调差
     app.get('/tender/:id/measure/material', sessionAuth, tenderCheck, 'materialController.index');
-    app.get('/tender/:id/measure/material/:order', sessionAuth, tenderCheck, materialCheck, 'materialController.info');
     app.post('/tender/:id/measure/material/add', sessionAuth, tenderCheck, 'materialController.add');
     app.post('/tender/:id/measure/material/delete', sessionAuth, tenderCheck, 'materialController.delete');
     // 审批
@@ -222,7 +221,10 @@ module.exports = app => {
     app.post('/tender/:id/measure/material/:order/audit/start', sessionAuth, tenderCheck, materialCheck, 'materialController.startAudit');
     app.post('/tender/:id/measure/material/:order/audit/check', sessionAuth, tenderCheck, materialCheck, 'materialController.checkAudit');
     // 调差工料
+    app.get('/tender/:id/measure/material/:order', sessionAuth, tenderCheck, materialCheck, 'materialController.info');
     app.post('/tender/:id/measure/material/:order/save', sessionAuth, tenderCheck, materialCheck, 'materialController.saveBillsData');
+    // 调差清单
+    app.get('/tender/:id/measure/material/:order/list', sessionAuth, tenderCheck, materialCheck, 'materialController.list');
 
     // 个人账号相关
     app.get('/profile/info', sessionAuth, 'profileController.info');

+ 3 - 2
app/service/revise_audit.js

@@ -361,9 +361,10 @@ module.exports = app => {
                 '    t.`id` As t_id, t.`name` As t_name, t.`project_id` As t_pid, t.`type` As t_type, t.`user_id` As t_uid, ' +
                 '    pa.name As `ru_name`, pa.role As `ru_role`, pa.company As `ru_company`' +
                 '  FROM ' + this.tableName + ' As ra' +
-                '  INNER JOIN ' + this.ctx.service.ledgerRevise.tableName + ' As r ON ra.audit_id <> ? and ra.end_time > ?' +
-                '  LEFT JOIN ' + this.ctx.service.tender.tableName + ' As t ON r.`tid` = t.`id` and t.project_id = ?' +
+                '  LEFT JOIN ' + this.ctx.service.ledgerRevise.tableName + ' As r ON ra.rid = r.id' +
+                '  LEFT JOIN ' + this.ctx.service.tender.tableName + ' As t ON r.`tid` = t.`id`' +
                 '  LEFT JOIN ' + this.ctx.service.projectAccount.tableName + ' As pa ON ra.`audit_id` = pa.`id`' +
+                '  WHERE ra.audit_id <> ? and ra.end_time > ? and t.project_id = ?' +
                 '  GROUP By t.`id`' +
                 '  ORDER By ra.`end_time`';
             const sqlParam = [auditorId, noticeTime, projectId];

+ 24 - 0
app/service/stage_bills.js

@@ -369,6 +369,30 @@ module.exports = app => {
         async getSumTotalPriceNotGcl(stage) {
             return await this.getSumTotalPriceFilter(stage, '=', this.db.escape(''));
         }
+
+        /**
+         * 多期清单数据整合 (材料调差调用)
+         * @param {Number} tid - 标段id
+         * @param {String} stage_id_list - 期id列表
+         * @returns {Promise<void>}
+         */
+        async getStagesData(tid, stage_id_list) {
+            let stage_id_listSql = '';
+            stage_id_list = stage_id_list.indexOf(',') !== -1 ? stage_id_list.split(',') : stage_id_list;
+            if (stage_id_list) {
+                if (stage_id_list instanceof Array) {
+                    stage_id_listSql = stage_id_list.length > 0 ? ' And sid in (' + this.ctx.helper.getInArrStrSqlFilter(stage_id_list) + ')' : '';
+                } else {
+                    stage_id_listSql = ' And sid in (' + this.db.escape(stage_id_list) + ')';
+                }
+            }
+            const sql = 'SELECT `lid`, `tid`, `sid`, SUM(`contract_qty`) as `contract_qty`, SUM(`contract_tp`) as `contract_tp`, ' +
+                'SUM(`qc_qty`) as `qc_qty`, SUM(`qc_tp`) as `qc_tp` FROM ' + this.tableName + ' WHERE `tid` = ? ' +
+                stage_id_listSql + ' GROUP BY `lid`';
+            const sqlParam = [tid];
+            const result = await this.db.query(sql, sqlParam);
+            return result;
+        }
     }
 
     return StageBills;

+ 25 - 1
app/service/stage_pos.js

@@ -451,7 +451,31 @@ module.exports = app => {
                 return await this.db.queryOne(calcQtySql, sqlParam);
             }
         }
+
+        /**
+         * 多期清单数据整合 (材料调差调用)
+         * @param {Number} tid - 标段id
+         * @param {String} stage_id_list - 期id列表
+         * @returns {Promise<void>}
+         */
+        async getStagesData(tid, stage_id_list) {
+            let stage_id_listSql = '';
+            stage_id_list = stage_id_list.indexOf(',') !== -1 ? stage_id_list.split(',') : stage_id_list;
+            if (stage_id_list) {
+                if (stage_id_list instanceof Array) {
+                    stage_id_listSql = stage_id_list.length > 0 ? ' And sid in (' + this.ctx.helper.getInArrStrSqlFilter(stage_id_list) + ')' : '';
+                } else {
+                    stage_id_listSql = ' And sid in (' + this.db.escape(stage_id_list) + ')';
+                }
+            }
+            const sql = 'SELECT `id`, `tid`, `sid`, `pid`, `lid`, SUM(`contract_qty`) as `contract_qty`, SUM(`qc_qty`) as `qc_qty`' +
+                ' FROM ' + this.tableName + ' WHERE `tid` = ? ' +
+                stage_id_listSql + 'GROUP BY `pid`';
+            const sqlParam = [tid];
+            const result = await this.db.query(sql, sqlParam);
+            return result;
+        }
     }
 
     return StagePos;
-};
+};

+ 76 - 0
app/view/material/list.ejs

@@ -0,0 +1,76 @@
+<% include ./material_sub_menu.ejs %>
+<div class="panel-content">
+    <div class="panel-title">
+        <div class="title-main d-flex justify-content-between">
+            <% include ./material_sub_mini_menu.ejs %>
+            <div>
+                <div class="d-inline-block">
+                    本期调差计量期:第<span class="mx-2"><%= ctx.material.s_order.split(',').join(',') %></span>期
+                </div>
+                <div class="d-inline-block ml-2">
+                    <a class="btn btn-sm btn-light">
+                        <div class="custom-control custom-checkbox">
+                            <input type="checkbox" class="custom-control-input" id="customCheckDisabled">
+                            <label class="custom-control-label text-primary" for="customCheckDisabled">显示有调差工料清单</label>
+                        </div>
+                    </a>
+                </div>
+            </div>
+            <div class="ml-auto">
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-header p-0">
+        </div>
+        <div class="row w-100 sub-content">
+            <div id="main-view" class="c-body" style="width: 100%">
+                <!--上部分-->
+                <div class="sjs-height-1" id="ledger-spread">
+                </div>
+                <!--下部分-->
+                <div class="bcontent-wrap">
+                    <div class="bc-bar mb-1">
+                        <ul class="nav nav-tabs">
+                            <li class="nav-item">
+                                <a class="nav-link active" data-toggle="tab" href="#xmujie" role="tab">清单明细</a>
+                            </li>
+                            <li class="ml-auto">
+                                <a class="btn btn-sm btn-primary" href="#">应用调差工料至其他清单明细</a>
+                            </li>
+                        </ul>
+                    </div>
+                    <div class="tab-content">
+                        <div class="tab-pane active" id="xmujie">
+                            <div class="row">
+                                <div class="col-8">
+                                    <div class="sp-wrap" id="leaf-xmj-spread">
+                                    </div>
+                                </div>
+                                <div class="col-4">
+                                    <div class="sp-wrap" id="material-spread">
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<% if ((ctx.material.status === auditConst.status.uncheck || ctx.material.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === ctx.material.user_id) {%>
+<script>
+    const accountList = JSON.parse('<%- JSON.stringify(accountList) %>');
+</script>
+<% } %>
+<script>
+    const materialType = JSON.parse('<%- materialType %>');
+    const materialBillsData = JSON.parse('<%- JSON.stringify(materialBillsData) %>');
+    const materialListData = JSON.parse('<%- JSON.stringify(materialListData) %>');
+    const ledger = JSON.parse('<%- JSON.stringify(ledger) %>');
+    const curLedgerData = JSON.parse('<%- JSON.stringify(curLedgerData) %>');
+    const pos = JSON.parse('<%- JSON.stringify(pos) %>');
+    const curPosData = JSON.parse('<%- JSON.stringify(curPosData) %>');
+    const readOnly = <%- material.readOnly %>;
+</script>

+ 1 - 1
app/view/tender/detail.ejs

@@ -765,5 +765,5 @@
     let property = JSON.parse('<%- JSON.stringify(tenderInfo) %>');
     let ledgerChecked = <%- tender.ldeger_status === audit.ledger.status.checked %>;
     <% console.log(lastStage) %>
-    let firstStageChecked = <%- lastStage !== undefined && lastStage !== null && (lastStage.order > 1 || (lastStage.order === 1 && lastStage.status !== audit.stage.status.checked)) %>;
+    let firstStageChecked = <%- lastStage !== undefined && lastStage !== null && (lastStage.order > 1 || (lastStage.order === 1 && lastStage.status === audit.stage.status.checked)) %>;
 </script>

+ 18 - 0
config/web.js

@@ -323,6 +323,24 @@ const JsFiles = {
                 ],
                 mergeFile: 'material',
             },
+            list: {
+                files: [
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/decimal.min.js",
+                    "/public/js/toastr.min.js",
+                ],
+                mergeFiles: [
+                    "/public/js/sub_menu.js",
+                    "/public/js/div_resizer.js",
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/zh_calc.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/gcl_gather.js",
+                    "/public/js/material_list.js",
+                    "/public/js/material_audit.js",
+                ],
+                mergeFile: 'material_list',
+            },
         },
     }