Просмотр исходного кода

Merge branch 'dev' of http://192.168.1.41:3000/maixinrong/Calculation into dev

Tony Kang 3 лет назад
Родитель
Сommit
6932d37a77

+ 6 - 3
app/const/spread.js

@@ -203,9 +203,10 @@ const stageTz = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_contract_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '截止本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qc_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_qc_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
-            {title: '截止本期完成计量|数量', colSpan: '3|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
+            {title: '截止本期完成计量|数量', colSpan: '4|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_gather_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
+            {title: '|1#完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_1_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
             {title: '合同|项目节数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'deal_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
             {title: '|项目节数量2',  colSpan: '|1', rowSpan: '|1', field: 'deal_dgn_qty2', hAlign: 2, width: 60, type: 'Number'},
             {title: '变更|项目节数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'c_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
@@ -281,9 +282,10 @@ const stageCl = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_contract_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '截止本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qc_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_qc_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
-            {title: '截止本期完成计量|数量', colSpan: '3|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
+            {title: '截止本期完成计量|数量', colSpan: '4|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_gather_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
+            {title: '|1#完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_1_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
             {title: '合同|项目节数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'deal_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
             {title: '|项目节数量2',  colSpan: '|1', rowSpan: '|1', field: 'deal_dgn_qty2', hAlign: 2, width: 60, type: 'Number'},
             {title: '变更|项目节数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'c_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
@@ -358,9 +360,10 @@ const stageNoCl = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_contract_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '截止本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qc_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_qc_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
-            {title: '截止本期完成计量|数量', colSpan: '3|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
+            {title: '截止本期完成计量|数量', colSpan: '4|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_gather_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
+            {title: '|1#完成率(%)', colSpan: '1', rowSpan: '|1', field: 'end_gather_1_percent', hAlign: 2, width: 80, readOnly: true, type: 'Number'},
             {title: '合同|项目节数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'deal_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
             {title: '|项目节数量2',  colSpan: '|1', rowSpan: '|1', field: 'deal_dgn_qty2', hAlign: 2, width: 60, type: 'Number'},
             {title: '变更|项目节数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'c_dgn_qty1', hAlign: 2, width: 60, type: 'Number'},

+ 1 - 1
app/const/wechat_template.js

@@ -19,7 +19,7 @@ const templateId = {
     stage: '5vU3WmR90yDajbs4LWIWH4OQhunYlS1HXTiesIGxrsk',
     change: 'nSKl9u4DMvu7KtmFFS9bfVvznRDRpx6L7LlTnVFn4fs', // 变更所有共用模板
     ledger: '9Ul3KFxvYQGfT6wbGGjqqnGR0zHtx0BHKs9sXj4Ii44', // 台账和台账修订共用模板
-    revise: 'ia3ObPVe_0A1GLVpU-jcDe1P6zVriJ36eAijeQvbpFM',
+    revise: '9Ul3KFxvYQGfT6wbGGjqqnGR0zHtx0BHKs9sXj4Ii44',
     material: 'Y9ov80rev3LHcoM2hOQE6jrK_5xZsqE-PZ0Z6HS9VGA',
     advance: 'rgZHkyiLzrqaSGnQ2nSCCrOdUz2RJJZ_JA34L_MnQik',
 };

+ 2 - 3
app/controller/report_archive_controller.js

@@ -581,7 +581,7 @@ module.exports = app => {
                 if (archiveEncryptions.length > 0) {
                     archiveEncryptionList = JSON.parse(archiveEncryptions[0].content);
                 }
-            } else {
+            } else if (stageList.length > 0 && stageList[0].status === auditConst.stage.status.checked) {
                 // console.log('stageList[0].id: ' + stageList[0].id);
                 // const archives = await ctx.service.rptArchive.getPrjStgArchive(tender.data.project_id, stageList[stageList.length - 1].id);
                 let archives = [];
@@ -592,8 +592,7 @@ module.exports = app => {
                         break;
                     }
                 }
-
-
+                ctx.stage = ctx.stage ? ctx.stage : stageList[stageList.length - 1];
                 const archiveEncryptions = await ctx.service.rptArchiveEncryption.getPrjStgArchiveEncryption(tender.data.project_id, ctx.stage.id);
                 // stage_id = stageList[0].id;
                 // stage_order = stageList[0].order;

+ 12 - 1
app/controller/stage_controller.js

@@ -350,6 +350,9 @@ module.exports = app => {
                         case 'changeBills':
                             responseData.data.changeBills = await this.ctx.service.changeAuditList.checkedChangeBills(ctx.stage.tid);
                             break;
+                        case 'minus_change':
+                            responseData.data.minus_change = await this.ctx.service.stageChangeFinal.getPreMinusChange(ctx.stage.tid, ctx.stage.order);
+                            break;
                         case 'import_change':
                             responseData.data.import_change = await this.ctx.service.stageImportChange.getStageImportData(this.ctx.stage);
                             break;
@@ -524,18 +527,22 @@ module.exports = app => {
                 if (!data.target || (!data.target.bills && !data.target.pos) || !data.change) {
                     throw '调用变更令数据错误';
                 }
-                let result;
+                let result, minus;
                 if (data.target.pos) {
                     result = await ctx.service.stageChange.posChange(data.target.pos, data.change);
                     result.change = { target: { lid: data.target.pos.lid, pid: data.target.pos.id } };
                     result.change.data = await ctx.service.stageChange.getLastestStageData(ctx.tender.id,
                         ctx.stage.id, data.target.pos.lid, data.target.pos.id);
+                    minus = await this.ctx.service.stageChange.getBillsMinusQty(ctx.stage, data.target.pos.lid);
                 } else {
                     result = await ctx.service.stageChange.billsChange(data.target.bills, data.change);
                     result.change = { target: { lid: data.target.bills.id, pid: '-1' } };
                     result.change.data = await ctx.service.stageChange.getLastestStageData(ctx.tender.id,
                         ctx.stage.id, data.target.bills.id, '-1');
+                    minus = await this.ctx.service.stageChange.getBillsMinusQty(ctx.stage, data.target.bills.id);
                 }
+                const bills = result.bills.curStageData.find(x => { return x.lid === minus.lid });
+                if (bills) bills.minus_qc_qty = minus.qty;
                 await ctx.service.stage.updateCheckCalcFlag(ctx.stage, true);
                 await ctx.service.stage.updateCacheTime(ctx.stage.id);
                 ctx.body = { err: 0, msg: '', data: result };
@@ -2077,6 +2084,8 @@ module.exports = app => {
 
                 const data = JSON.parse(ctx.request.body.data);
                 await ctx.service.stageStash.recover(ctx.stage, data.id);
+                await ctx.service.stage.updateCheckCalcFlag(ctx.stage, true);
+                await ctx.service.stage.updateCacheTime(ctx.stage.id);
                 ctx.body = { err: 0, msg: '', data: null };
             } catch (err) {
                 ctx.log(err);
@@ -2102,6 +2111,8 @@ module.exports = app => {
                 const compressData = ctx.request.body.data;
                 const data = JSON.parse(LzString.decompressFromUTF16(compressData));
 
+                await ctx.service.stage.updateCheckCalcFlag(ctx.stage, true);
+                await ctx.service.stage.updateCacheTime(ctx.stage.id);
             } catch (err) {
                 ctx.log(err);
                 ctx.ajaxErrorBody(err, '导入计量台账数据错误');

+ 118 - 33
app/lib/analysis_excel.js

@@ -12,6 +12,18 @@ const colDefineType = {
     match: 1,
     pos: 2,
 };
+
+const mainReg = /^(GD*)?G?(\d\d)*\d$/i;
+const subReg = /^(GD*)?G?[A-Z]{2}(\d\d)+$/i;
+const gdXmjPartReg = /^(GD*)?G?/;
+const specCode106 = {
+    code: ['102', '103', '104'],
+    reg: /^(GD*)?G?106/i
+};
+const specCode109 = {
+    code: ['102', '103', '104', '105', '106', '107', '108'],
+    reg: /^(GD*)?G?109/i
+};
 const aeUtils = {
     toNumber: function (value) {
         let num = _.toNumber(value);
@@ -42,21 +54,19 @@ const aeUtils = {
             }
         }
         return colsDef;
+    },
+    isMatch11(tempData) {
+        return _.find(tempData, x => {
+            return x.code.indexOf('-') > 0;
+        })
+    },
+    isMatch18(tempData) {
+        return _.every(tempData, x => {
+            return !x.code || !!x.code.match(mainReg);
+        });
     }
 };
 
-const mainReg = /^(GD*)?G?(\d\d)*\d$/i;
-const subReg = /^(GD*)?G?[A-Z]{2}(\d\d)+$/i;
-const gdXmjPartReg = /^(GD*)?G?/;
-const specCode106 = {
-    code: ['102', '103', '104'],
-    reg: /^(GD*)?G?106/i
-};
-const specCode109 = {
-    code: ['102', '103', '104', '105', '106', '107', '108'],
-    reg: /^(GD*)?G?109/i
-};
-
 class ImportBaseTree {
     /**
      * 构造函数
@@ -362,11 +372,9 @@ class ImportStd18Tree extends ImportBaseTree {
      * @private
      */
     _checkParent(parent, code) {
-        if (code === 'LJ0703') console.log(parent.code, code);
         const codeNumberPart = code.replace(gdXmjPartReg, '');
         if (!parent.code) return false;
         const numberPart = parent.code.replace(gdXmjPartReg, '');
-        if (code === 'LJ0703') console.log(numberPart, codeNumberPart);
         if (!numberPart || !codeNumberPart || numberPart.length >= codeNumberPart.length) return false;
         return code.indexOf(numberPart) === 0 ||
             code.indexOf('G' + numberPart) === 0 ||
@@ -515,24 +523,12 @@ class AnalysisExcelTree {
         this.needCols = needCols || ['code', 'b_code', 'pos'];
     }
 
-    _isMatch11(tempData) {
-        return _.find(tempData, x => {
-            return x.code.indexOf('-') > 0;
-        })
-    }
-
-    _isMatch18(tempData) {
-        return _.every(tempData, x => {
-            return !x.code || !!x.code.match(mainReg);
-        });
-    }
-
     _getNewCacheTree(tempData) {
         // 模板符合11编办规则,使用11编办树
-        if (this._isMatch18(tempData)) {
+        if (aeUtils.isMatch18(tempData)) {
             return new ImportStd18Tree(tempData, this.ctx, this.setting);
         // 反之使用11编办(未校验模板是否符合,替换注释部分即可实现)
-        // } else if (this._isMatch11(tempData)){
+        // } else if (aeUtils.isMatch11(tempData)){
         } else {
             return new ImportBaseTree(tempData, this.ctx, this.setting);
         }
@@ -552,12 +548,12 @@ class AnalysisExcelTree {
             node.unit = this.ctx.helper.replaceReturn(row[this.colsDef.unit]);
             node.dgn_qty1 = aeUtils.toNumber(row[this.colsDef.dgn_qty1]);
             node.dgn_qty2 = aeUtils.toNumber(row[this.colsDef.dgn_qty2]);
-            node.total_price = this.ctx.helper.round(aeUtils.toNumber(row[this.colsDef.total_price]), this.decimal.tp);
+            // 2022-6-9 曾沛文要求不导入金额
+            //node.total_price = this.ctx.helper.round(aeUtils.toNumber(row[this.colsDef.total_price]), this.decimal.tp);
             node.drawing_code = this.ctx.helper.replaceReturn(row[this.colsDef.drawing_code]);
             node.memo = this.ctx.helper.replaceReturn(row[this.colsDef.memo]);
             return this.cacheTree.addXmjNode(node);
         } catch (error) {
-            console.log(error);
             if (error.stack) {
                 this.ctx.logger.error(error);
             } else {
@@ -676,8 +672,6 @@ class AnalysisExcelTree {
                 this.checkColHeader(row);
             }
         }
-        this.cacheTree.resortFirstPartChildren();
-        if (!this.filter.filterCalc) this.cacheTree.calculateLeafWithPos();
         return this.cacheTree;
     }
 }
@@ -883,4 +877,95 @@ class AnalysisGclExcelTree {
     }
 }
 
-module.exports = { AnalysisExcelTree, AnalysisGclExcelTree };
+class ImportStageBaseTree {
+
+}
+
+class AnalysisStageTree {
+    /**
+     * 构造函数
+     */
+    constructor(ctx, setting) {
+        this.ctx = ctx;
+        this.setting = setting;
+        this.mid = ctx.tender.id;
+        this.decimal = ctx.tender.info.decimal;
+        this.precision = ctx.tender.info.precision;
+        this.colsDef = null;
+        this.colHeaderMatch = {
+            code: {value: ['项目节编号', '预算项目节'], type: colDefineType.match},
+            b_code: {value: ['清单子目号', '清单编号', '子目号'], type: colDefineType.match},
+            pos: {value: ['计量单元'], type: colDefineType.match},
+            name: {value: ['名称'], type: colDefineType.match},
+            unit: {value: ['单位'], type: colDefineType.match},
+            contract_qty: {value: ['本期合同计量|数量'], type: colDefineType.match},
+            contract_tp: {value: ['本期合同计量|金额'], type: colDefineType.match},
+        };
+        this.needCols = ['code', 'b_code', 'pos', 'name', 'unit', 'contract_qty', 'contract_tp'];
+    }
+
+    /**
+     * 读取表头并检查
+     * @param {Number} row - Excel数据行
+     */
+    checkColHeader(row) {
+        const colsDef = aeUtils.checkColHeader(row, this.colHeaderMatch);
+        let check = true;
+        for (const col of this.needCols) {
+            if (!colsDef[col]) check = false;
+        }
+        if (check) this.colsDef = colsDef;
+    }
+
+    mergeHeaderRow(iRow, row, subRow, merge) {
+        const result = [];
+        for (let iCol = 0, iLen = row.length; iCol < iLen; iCol++) {
+            const colMerge = merge.find(x => { return x.s.c === iCol && x.s.r === iRow});
+            if (colMerge && colMerge.s.c !== colMerge.e.c) {
+                let iSubCol = iCol;
+                while (iSubCol <= colMerge.e.c) {
+                    result.push(row[iCol] + '|' + subRow[iSubCol]);
+                    iSubCol++;
+                }
+                iCol = colMerge.e.c;
+            } else {
+                result.push(row[iCol])
+            }
+        }
+        return result;
+    }
+
+    loadRowData(row, iRow) {
+
+    }
+
+    /**
+     * 将excel清单 平面数据 解析为 树结构数据
+     * @param {object} sheet - excel清单数据
+     * @param {Array} tempData - 新建项目使用的清单模板
+     * @returns {ImportBaseTree}
+     */
+    analysisData(ledger, pos, sheet) {
+        this.filter = filter ? filter : {};
+        this.colsDef = null;
+        this.cacheTree = this._getNewLedger();
+        this.errorData = [];
+        this.loadEnd = false;
+        this.loadBegin = sheet.rows.length;
+
+        for (const iRow in sheet.rows) {
+            if (this.colsDef && !this.loadEnd) {
+                if (iRow < this.loadBegin) continue;
+                this.loadRowData(sheet.rows[iRow], iRow);
+            } else {
+                const mergeRow = this.mergeHeaderRow(iRow, sheet.rows[iRow], sheet.rows[iRow + 1], sheet.merge);
+                this.checkColHeader(mergeRow);
+                if (this.colsDef) this.loadBegin = iRow + 2;
+            }
+        }
+
+        return this.cacheTree;
+    }
+}
+
+module.exports = { AnalysisExcelTree, AnalysisGclExcelTree, AnalysisStageTree };

+ 24 - 3
app/lib/budget_final.js

@@ -192,6 +192,20 @@ class BudgetFinal {
             node.dgn_qty = node.dgn_qty1
                 ? (node.dgn_qty2 ? node.dgn_qty1 + '/' + node.dgn_qty2 : node.dgn_qty1)
                 : (node.dgn_qty2 ? '/' + node.dgn_qty2 : '');
+
+            node.gu_dgn_price = helper.div(node.gu_tp, node.gu_dgn_qty1, 2);
+            node.gu_dgn_qty = node.gu_dgn_qty1
+                ? (node.gu_dgn_qty2 ? node.gu_dgn_qty1 + '/' + node.gu_dgn_qty2 : node.gu_dgn_qty1 + '')
+                : (node.gu_dgn_qty2 ? '/' + node.gu_dgn_qty2 : '');
+            node.gai_dgn_price = helper.div(node.gai_tp, node.gai_dgn_qty1, 2);
+            node.gai_dgn_qty = node.gai_dgn_qty1
+                ? (node.gai_dgn_qty2 ? node.gai_dgn_qty1 + '/' + node.gai_dgn_qty2 : node.gai_dgn_qty1 + '')
+                : (node.gai_dgn_qty2 ? '/' + node.gai_dgn_qty2 : '');
+            node.yu_dgn_price = helper.div(node.yu_tp, node.yu_dgn_qty1, 2);
+            node.yu_dgn_qty = node.yu_dgn_qty1
+                ? (node.yu_dgn_qty2 ? node.yu_dgn_qty1 + '/' + node.yu_dgn_qty2 : node.yu_dgn_qty1 + '')
+                : (node.yu_dgn_qty2 ? '/' + node.yu_dgn_qty2 : '');
+
             node.final_dgn_price = helper.div(node.final_tp, node.final_dgn_qty1, 2);
             node.final_dgn_qty = node.final_dgn_qty1
                 ? (node.final_dgn_qty2 ? node.final_dgn_qty1 + '/' + node.final_dgn_qty2 : node.final_dgn_qty1)
@@ -203,6 +217,13 @@ class BudgetFinal {
                 : (node.grow_dgn_qty2 ? '/' + node.grow_dgn_qty2 : '');
             node.grow_tp = helper.mul(helper.div(helper.sub(node.final_tp, node.gai_tp), node.gai_tp, 4), 100);
         });
+        this.finalTree.resortChildrenByCustom(function (x, y) {
+            const iCode = helper.compareCode(x.code, y.code);
+            if (iCode) return iCode;
+            if (!x.name) return -1;
+            if (!y.name) return 1;
+            return x.name.localeCompare(y.name);
+        });
     }
 
     getFinalData() {
@@ -212,9 +233,9 @@ class BudgetFinal {
                 id: ctx.app.uuid.v4(), bid, final_id,
                 tree_id: x.id, tree_pid: x.pid, order: x.order, level: x.level, full_path: x.full_path, is_leaf: x.is_leaf,
                 code: x.code, name: x.name, unit: x.unit,
-                gu_dgn_qty1: x.gu_dgn_qty1 || 0, gu_dgn_qty2: x.gu_dgn_qty2 || 0, gu_tp: x.gu_tp || 0,
-                gai_dgn_qty1: x.gai_dgn_qty1 || 0, gai_dgn_qty2: x.gu_dgn_qty2 || 0, gai_tp: x.gu_tp || 0,
-                yu_dgn_qty1: x.yu_dgn_qty1 || 0, yu_dgn_qty2: x.yu_dgn_qty2 || 0, yu_tp: x.yu_tp || 0,
+                gu_dgn_qty1: x.gu_dgn_qty1 || 0, gu_dgn_qty2: x.gu_dgn_qty2 || 0, gu_dgn_qty: x.gu_dgn_qty, gu_dgn_price: x.gu_dgn_price || 0, gu_tp: x.gu_tp || 0,
+                gai_dgn_qty1: x.gai_dgn_qty1 || 0, gai_dgn_qty2: x.gai_dgn_qty2 || 0, gai_dgn_qty: x.gai_dgn_qty, gai_dgn_price: x.gai_dgn_price || 0, gai_tp: x.gai_tp || 0,
+                yu_dgn_qty1: x.yu_dgn_qty1 || 0, yu_dgn_qty2: x.yu_dgn_qty2 || 0, yu_dgn_qty: x.yu_dgn_qty, yu_dgn_price: x.yu_dgn_price || 0, yu_tp: x.yu_tp || 0,
 
                 dgn_qty1: x.dgn_qty1 || 0, dgn_qty2: x.dgn_qty2 || 0, total_price: x.total_price || 0,
                 final_dgn_qty1: x.final_dgn_qty1 || 0, final_dgn_qty2: x.final_dgn_qty2 || 0, final_tp: x.final_tp || 0,

+ 1 - 1
app/lib/gcl_gather.js

@@ -85,7 +85,7 @@ const gclGatherModel = class {
      * @constructor
      */
     CheckPeg(text) {
-        const pegReg = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+        const pegReg = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
         return pegReg.test(text);
     }
 

+ 3 - 3
app/lib/rm/budget.js

@@ -25,16 +25,16 @@ class reportMemoryBudget {
         return tree.getDefaultDatas();
     }
     async budgetYu(bid) {
-        const yu = await this.ctx.service.budgetGai.getAllDataByCondition({ where: { bid } });
+        const yu = await this.ctx.service.budgetYu.getAllDataByCondition({ where: { bid } });
         const tree = new ledger.billsTree(this.ctx, { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] });
         tree.loadDatas(yu);
         tree.calculateAll();
         return tree.getDefaultDatas();
     }
     async budgetGu(bid) {
-        const yu = await this.ctx.service.budgetGai.getAllDataByCondition({ where: { bid } });
+        const gu = await this.ctx.service.budgetGu.getAllDataByCondition({ where: { bid } });
         const tree = new ledger.billsTree(this.ctx, { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] });
-        tree.loadDatas(yu);
+        tree.loadDatas(gu);
         tree.calculateAll();
         return tree.getDefaultDatas();
     }

+ 4 - 4
app/lib/stage_im.js

@@ -145,21 +145,21 @@ class StageIm {
         return cur;
     }
     _checkPeg(text) {
-        const pegReg = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+        const pegReg = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
         return pegReg.test(text);
     }
     _getPegStr(text) {
-        const pegReg1 = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?[~~—][a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+        const pegReg1 = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?[~~—][a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
         const result1 = text.match(pegReg1);
         if (result1) {
             return result1[0];
         }
-        const pegReg2 = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?-[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+        const pegReg2 = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?-[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
         const result2 = text.match(pegReg2);
         if (result2) {
             return result2[0];
         }
-        const pegReg3 = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+        const pegReg3 = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
         const result3 = text.match(pegReg3);
         return result3 ? result3[0] : '';
 

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

@@ -96,7 +96,6 @@ $(document).ready(() => {
                 cur.yu_tp = ZhCalc.add(cur.yu_tp, source.total_price);
             });
             compareTree.afterLoad(node => {
-                if (node.code === '1')console.log(node);
                 node.gu_dgn_price = ZhCalc.div(node.gu_tp, node.gu_dgn_qty1, 2);
                 node.gu_dgn_qty = node.gu_dgn_qty1
                     ? (node.gu_dgn_qty2 ? node.gu_dgn_qty1 + '/' + node.gu_dgn_qty2 : node.gu_dgn_qty1)

+ 2 - 2
app/public/js/change_information_set.js

@@ -914,7 +914,7 @@ $(document).ready(() => {
         const data_bwmx = $(this).attr('data-bwmx').split('$#$');
         const data_charu = $(this).attr('data-charu') ? $(this).attr('data-charu').split('$#$') : [];
         const isDeal = $(this).data('gcl') !== undefined ? true : false;
-        let codeHtml = '<tr quantity="'+ $(this).children('td').eq(5).text() +'" gcl_id="" mx_id=""><td class="text-center">1</td><td colspan="7" class="colspan_1">&nbsp;</td><td class="colspan_2"><input type="checkbox"></td></tr>';
+        let codeHtml = '<tr quantity="'+ $(this).children('td').eq(5).text() +'" gcl_id="" mx_id=""><td class="text-center">1</td><td colspan="7" class="colspan_1">&nbsp;</td><td class="colspan_2 text-center"><input type="checkbox"></td></tr>';
         if (isDeal) {
             const lid = $(this).data('lid');
             let gcl = _.find(gclGatherData, function (item) {
@@ -955,7 +955,7 @@ $(document).ready(() => {
             const pushMsg = '0*;*' + $(this).children('td').eq(5).text();
             const isChecked = data_bwmx.indexOf(pushMsg) !== -1 && isCheck ? 'checked ' : '';
             const isDisabeld = changeOrder && isChecked && data_charu.indexOf(pushMsg) === -1 ? 'disabled ' : '';
-            codeHtml = '<tr quantity="'+ $(this).children('td').eq(5).text() +'" gcl_id="" mx_id=""><td class="text-center">1</td><td colspan="7" class="colspan_1">&nbsp;</td><td class="colspan_2"><input type="checkbox" ' + isChecked + isDisabeld +'></td></tr>';
+            codeHtml = '<tr quantity="'+ $(this).children('td').eq(5).text() +'" gcl_id="" mx_id=""><td class="text-center">1</td><td colspan="7" class="colspan_1">&nbsp;</td><td class="colspan_2 text-center"><input type="checkbox" ' + isChecked + isDisabeld +'></td></tr>';
         }
         $('#code-list').attr('data-index', parseInt($(this).children('td').eq(0).text()));
         $('#code-input').val('');

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

@@ -128,7 +128,7 @@ const gclGatherModel = (function () {
      * @constructor
      */
     function CheckPeg(text) {
-        const pegReg = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+        const pegReg = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
         return pegReg.test(text);
     }
 

+ 1 - 1
app/public/js/shares/gcl_gather_compare.js

@@ -67,7 +67,7 @@ const gclCompareModel = (function () {
      * @constructor
      */
     function CheckPeg(text) {
-        const pegReg = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+        const pegReg = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
         return pegReg.test(text);
     }
 

+ 30 - 5
app/public/js/stage.js

@@ -36,7 +36,7 @@ function customColDisplay () {
         { title: '本期完成计量', fields: ['gather_qty', 'gather_tp'], visible: true },
         { title: '截止本期计量合同', fields: ['end_contract_qty', 'end_contract_tp'], visible: true },
         { title: '截止本期数量变更', fields: ['end_qc_qty', 'end_qc_tp', 'end_qc_bgl'], visible: true },
-        { title: '截止本期完成计量', fields: ['end_gather_qty', 'end_gather_tp', 'end_gather_percent'], visible: true },
+        { title: '截止本期完成计量', fields: ['end_gather_qty', 'end_gather_tp', 'end_gather_percent', 'end_gather_1_percent'], visible: true },
         { title: '本期批注', fields: ['postil'], visible: true },
         { title: '图册号', fields: ['drawing_code'], visible: true },
         { title: '备注', fields: ['memo'], visible: true },
@@ -267,9 +267,9 @@ $(document).ready(() => {
         markExpandSubKey: window.location.pathname.split('/')[2],
     };
     // 台账树结构计算相关设置
-    stageTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil', 'used', 'contract_expr'];
+    stageTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil', 'used', 'contract_expr', 'minus_qc_qty'];
     stageTreeSetting.calcFields = ['deal_tp', 'total_price', 'contract_tp', 'qc_tp', 'gather_tp',
-        'pre_contract_tp', 'pre_qc_tp', 'pre_gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp', 'end_correct_tp'];
+        'pre_contract_tp', 'pre_qc_tp', 'pre_gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp', 'end_correct_tp', 'end_1_tp'];
     stageTreeSetting.calcFun = function (node) {
         if (!node.children || node.children.length === 0) {
             node.pre_gather_qty = ZhCalc.add(node.pre_contract_qty, node.pre_qc_qty);
@@ -277,6 +277,9 @@ $(document).ready(() => {
             node.end_contract_qty = ZhCalc.add(node.pre_contract_qty, node.contract_qty);
             node.end_qc_qty = ZhCalc.add(node.pre_qc_qty, node.qc_qty);
             node.end_gather_qty = ZhCalc.add(node.pre_gather_qty, node.gather_qty);
+            node.end_minus_qc_qty = ZhCalc.add(node.pre_minus_qc_qty, node.minus_qc_qty);
+            node.end_1_qty = ZhCalc.add(node.end_minus_qc_qty, node.quantity); // 1#台账 台账+负变更
+            node.end_1_tp = ZhCalc.mul(node.unit_price, node.end_1_qty, tenderInfo.decimal.tp);
         }
         node.pre_gather_tp = ZhCalc.add(node.pre_contract_tp, node.pre_qc_tp);
         node.gather_tp = ZhCalc.add(node.contract_tp, node.qc_tp);
@@ -284,6 +287,7 @@ $(document).ready(() => {
         node.end_qc_tp = ZhCalc.add(node.pre_qc_tp, node.qc_tp);
         node.end_gather_tp = ZhCalc.add(node.pre_gather_tp, node.gather_tp);
         node.end_final_tp = ZhCalc.add(node.end_qc_tp, node.total_price);
+        node.end_final_1_tp = ZhCalc.add(node.end_qc_tp, node.end_1_tp);
         if (!node.children || node.children.length === 0) {
             if (node.end_contract_qty) {
                 node.end_correct_tp = ZhCalc.add(node.end_qc_tp, ZhCalc.mul(node.end_contract_qty, node.unit_price, tenderInfo.decimal.tp));
@@ -293,6 +297,8 @@ $(document).ready(() => {
         }
         node.end_gather_percent = ZhCalc.mul(ZhCalc.div(node.end_gather_tp, node.end_final_tp), 100, 2);
         node.end_correct_percent = ZhCalc.mul(ZhCalc.div(node.end_correct_tp, node.end_final_tp), 100, 2);
+        node.end_gather_1_percent = ZhCalc.mul(ZhCalc.div(node.end_gather_tp, node.end_final_1_tp), 100, 2);
+        node.end_correct_1_percent = ZhCalc.mul(ZhCalc.div(node.end_correct_tp, node.end_final_1_tp), 100, 2);
         node.final_dgn_price = ZhCalc.round(ZhCalc.div(node.end_gather_tp, ZhCalc.add(node.deal_dgn_qty1, node.c_dgn_qty1)), tenderInfo.decimal.up);
     };
     const stageTree = createNewPathTree('stage', stageTreeSetting);
@@ -502,7 +508,7 @@ $(document).ready(() => {
                             return;
                         }
 
-                        data.change.push({ cid: c.cid, cbid: c.cbid, qty: c.uamount });
+                        data.change.push({ cid: c.cid, cbid: c.cbid, qty: c.uamount, minus: c.bamount < 0 });
                     }
                 }
                 // 提交数据到后端
@@ -651,6 +657,8 @@ $(document).ready(() => {
     };
     const ratioCol = ledgerSpreadSetting.cols.find(x => {return x.field === 'end_gather_percent' || x.field === 'end_correct_percent'});
     ratioCol.field = tenderInfo.display.stage.correct ? 'end_correct_percent' : 'end_gather_percent';
+    const ratioCol1 = ledgerSpreadSetting.cols.find(x => {return x.field === 'end_gather_1_percent' || x.field === 'end_correct_1_percent'});
+    ratioCol1.field = tenderInfo.display.stage.correct ? 'end_correct_1_percent' : 'end_gather_1_percent';
     ledgerSpreadSetting.imageClick = function (data, hitinfo) {
         const col = hitinfo.sheet.zh_setting.cols[hitinfo.col];
         switch (col.field) {
@@ -2032,9 +2040,26 @@ $(document).ready(() => {
     });
 
     // 加载计量单元数据 - 暂时统一加载,如有需要,切换成动态加载并缓存
-    postData(window.location.pathname + '/load', { filter: 'ledger;pos;detail;change;import_change;tag;cooperation' }, function (result) {
+    postData(window.location.pathname + '/load', { filter: 'ledger;pos;detail;change;import_change;tag;cooperation;minus_change' }, function (result) {
         // 加载树结构
         stageTree.loadDatas(result.ledgerData);
+        let mcIndex = {};
+        if (result.minus_change && result.minus_change.length > 0) {
+            for (const mc of result.minus_change) {
+                if (!mcIndex[mc.lid]) mcIndex[mc.lid] = stageTree.nodes.find(x => { return x.id === mc.lid; });
+                if (!mcIndex[mc.lid]) continue;
+                mcIndex[mc.lid].pre_minus_qc_qty = ZhCalc.add(mcIndex[mc.lid].pre_minus_qc_qty, mc.qty);
+            }
+        }
+        if (result.changeData && result.changeData.length > 0) {
+            for (const mc of result.changeData) {
+                if (!mc.minus || !mc.qty) continue;
+                if (!mcIndex[mc.lid]) mcIndex[mc.lid] = stageTree.nodes.find(x => { return x.id === mc.lid; });
+                if (!mcIndex[mc.lid]) continue;
+                mcIndex[mc.lid].minus_qc_qty = ZhCalc.add(mcIndex[mc.lid].minus_qc_qty, mc.qty);
+            }
+        }
+        mcIndex = null;
         checkShowLast(result.ledgerData.length);
         treeCalc.calculateAll(stageTree);
         // 加载解锁相关

+ 4 - 4
app/public/js/stage_im.js

@@ -159,22 +159,22 @@ const stageIm = (function () {
     }
 
     function CheckPeg(text) {
-        const pegReg = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+        const pegReg = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
         return pegReg.test(text);
     }
 
     function getPegStr(text) {
-        const pegReg1 = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?[~~—][a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+        const pegReg1 = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?[~~—][a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
         const result1 = text.match(pegReg1);
         if (result1) {
             return result1[0];
         } else {
-            const pegReg2 = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?-[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+            const pegReg2 = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?-[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
             const result2 = text.match(pegReg2);
             if (result2) {
                 return result2[0];
             } else {
-                const pegReg3 = /[a-zA-Z]?[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
+                const pegReg3 = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
                 const result3 = text.match(pegReg3);
                 return result3 ? result3[0] : '';
             }

+ 0 - 1
app/service/material_list.js

@@ -548,7 +548,6 @@ module.exports = app => {
                         });
                     }
                 }
-                console.log(updateDatas);
                 if (updateDatas.length > 0) await transaction.updateRows(this.tableName, updateDatas);
                 if (updateListGcl.length > 0) await transaction.updateRows(this.service.materialListGcl.tableName, updateListGcl);
                 await this.calcQuantityByML(transaction, mb_id);

+ 46 - 33
app/service/stage_change.js

@@ -131,17 +131,13 @@ module.exports = app => {
          */
         async billsChange(bills, changes) {
             const self = this;
-            function getNewChange(cid, cbid, times, order, qty) {
+            function getNewChange(cid, cbid, times, order, qty, minus) {
                 return {
-                    tid: self.ctx.tender.id,
-                    sid: self.ctx.stage.id,
-                    lid: bills.id,
-                    pid: -1,
-                    cid,
-                    cbid,
-                    stimes: times,
-                    sorder: order,
-                    qty,
+                    tid: self.ctx.tender.id, sid: self.ctx.stage.id,
+                    lid: bills.id, pid: -1,
+                    cid, cbid,
+                    stimes: times, sorder: order,
+                    qty, minus
                 };
             }
             const ledgerBills = await this.ctx.service.ledger.getDataById(bills.id);
@@ -159,8 +155,10 @@ module.exports = app => {
                 const nc = this._.find(changes, { cid: oc.cid, cbid: oc.cbid });
                 if (!nc || nc.qty !== oc.qty) {
                     const qty = nc ? this.round(nc.qty, precision.value) : null;
-                    const change = getNewChange(oc.cid, oc.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, qty);
-                    billsQty = this.ctx.helper.add(billsQty, change.qty);
+                    const change = getNewChange(oc.cid, oc.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, qty, nc ? nc.minus : oc.minus);
+                    if (!change.minus) {
+                        billsQty = this.ctx.helper.add(billsQty, change.qty);
+                    }
                     if (oc.stimes === this.ctx.stage.curTimes && oc.sorder === this.ctx.stage.curOrder) {
                         change.id = oc.id;
                         updateChanges.push(change);
@@ -168,14 +166,18 @@ module.exports = app => {
                         newChanges.push(change);
                     }
                 } else {
-                    billsQty = this.ctx.helper.add(billsQty, oc.qty);
+                    if (!oc.minus) {
+                        billsQty = this.ctx.helper.add(billsQty, oc.qty);
+                    }
                 }
             }
             for (const c of changes) {
                 const nc = this._.find(oldChanges, { cid: c.cid, cbid: c.cbid });
                 if (!nc) {
-                    const change = getNewChange(c.cid, c.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, this.round(c.qty, precision.value));
-                    billsQty = this.ctx.helper.add(billsQty, change.qty);
+                    const change = getNewChange(c.cid, c.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, this.round(c.qty, precision.value), c.minus);
+                    if (!change.minus) {
+                        billsQty = this.ctx.helper.add(billsQty, change.qty);
+                    }
                     newChanges.push(change);
                 }
             }
@@ -208,17 +210,13 @@ module.exports = app => {
          */
         async posChange(pos, changes) {
             const self = this;
-            function getNewChange(cid, cbid, times, order, qty) {
+            function getNewChange(cid, cbid, times, order, qty, minus) {
                 return {
-                    tid: self.ctx.tender.id,
-                    sid: self.ctx.stage.id,
-                    lid: pos.lid,
-                    pid: pos.id,
-                    cid,
-                    cbid,
-                    stimes: times,
-                    sorder: order,
-                    qty,
+                    tid: self.ctx.tender.id, sid: self.ctx.stage.id,
+                    lid: pos.lid, pid: pos.id,
+                    cid, cbid,
+                    stimes: times, sorder: order,
+                    qty, minus
                 };
             }
             const ledgerBills = await this.ctx.service.ledger.getDataById(pos.lid);
@@ -235,23 +233,27 @@ module.exports = app => {
                 const nc = this._.find(changes, { cid: oc.cid, cbid: oc.cbid });
                 if (!nc || nc.qty !== oc.qty) {
                     const qty = nc ? this.round(nc.qty, precision.value) : null;
-                    const change = getNewChange(oc.cid, oc.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, qty);
-                    posQty = this.ctx.helper.add(posQty, change.qty);
+                    const change = getNewChange(oc.cid, oc.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, qty, nc ? nc.minus : oc.minus);
+                    if (!change.minus) {
+                        posQty = this.ctx.helper.add(posQty, change.qty);
+                    }
                     if (oc.stimes === this.ctx.stage.curTimes && oc.sorder === this.ctx.stage.curOrder) {
                         change.id = oc.id;
                         updateChanges.push(change);
-                    } else {
-                        newChanges.push(change);
                     }
                 } else {
-                    posQty = this.ctx.helper.add(posQty, oc.qty);
+                    if (!oc.minus) {
+                        posQty = this.ctx.helper.add(posQty, oc.qty);
+                    }
                 }
             }
             for (const c of changes) {
                 const nc = this._.find(oldChanges, { cid: c.cid, cbid: c.cbid });
                 if (!nc) {
-                    const change = getNewChange(c.cid, c.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, this.round(c.qty, precision.value));
-                    posQty = this.ctx.helper.add(posQty, change.qty);
+                    const change = getNewChange(c.cid, c.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, this.round(c.qty, precision.value), c.minus);
+                    if (!change.minus) {
+                        posQty = this.ctx.helper.add(posQty, change.qty);
+                    }
                     newChanges.push(change);
                 }
             }
@@ -401,7 +403,7 @@ module.exports = app => {
             data = helper.filterLastestData(data, ['lid', 'pid', 'cbid'], 'stimes', 'sorder');
             const bqData = [];
             for (const d of data) {
-                if (!d.qty) continue;
+                if (!d.qty || d.minus) continue;
                 let bd = bqData.find(x => { return x.lid === d.lid && x.quality === d.quality; });
                 if (!bd) {
                     const bills = await this.db.get(this.ctx.service.ledger.departTableName(tender.id), { id: d.lid });
@@ -485,6 +487,17 @@ module.exports = app => {
             }
             return change;
         }
+
+        async getStageMinusChange(stage) {
+            const data = this.getAllDataByCondition({ where: { sid: stage.id, minus: 1 } });
+            return this.ctx.helper.filterLastestData(data, ['lid', 'pid', 'cbid'], 'stimes', 'sorder');
+        };
+
+        async getBillsMinusQty(stage, lid) {
+            const data = await this.getAllDataByCondition({ where: { sid: stage.id, lid, minus: 1 } });
+            const filter = this.ctx.helper.filterLastestData(data, ['lid', 'pid', 'cbid'], 'stimes', 'sorder');
+            return { lid, qty: this.ctx.helper.sum(filter.map(x => { return x.qty; })) };
+        };
     }
 
     return StageChange;

+ 13 - 1
app/service/stage_change_final.js

@@ -64,7 +64,7 @@ module.exports = app => {
                 data.push({
                     tid: c.tid, sid: c.sid, sorder: stage.order,
                     lid: c.lid, pid: c.pid, cid: c.cid, cbid: c.cbid,
-                    qty: c.qty,
+                    qty: c.qty, minus: c.minus,
                 });
             }
             if (data.length > 0) await transaction.insert(this.tableName, data);
@@ -101,6 +101,18 @@ module.exports = app => {
             const usedQty = await this.db.queryOne('Select SUM(qty) as qty FROM ' + this.tableName + ' WHERE cbid = ?', [cbid]);
             return usedQty ? this.ctx.helper.sub(qty, usedQty.qty) : qty;
         }
+
+        async getPreMinusChange(tid, sorder) {
+            const sql = 'SELECT lid, pid, SUM(qty) FROM ' + this.tableName + ' WHERE tid = ? and sorder < ? GROUP BY lid, pid';
+            const data = await this.db.query(sql, [tid, sorder]);
+            return data;
+        }
+
+        async getMinusChange(tid) {
+            const sql = 'SELECT lid, pid, SUM(qty) FROM ' + this.tableName + ' WHERE tid = ? GROUP BY lid, pid';
+            const data = await this.db.query(sql, [tid]);
+            return data;
+        }
     }
 
     return StageChangeFinal;

+ 4 - 4
app/service/stage_stash.js

@@ -110,11 +110,11 @@ module.exports = app => {
                         if (bp.change) {
                             for (const c of bp.change) {
                                 if (!c.qty) continue;
-                                const ncs = { tid: stage.tid, sid: stage.id, lid: b.id, pid: p.id, stimes: 1, sorder: 0, cid: c.cid, cbid: c.cbid };
+                                const ncs = { tid: stage.tid, sid: stage.id, lid: b.id, pid: p.id, stimes: 1, sorder: 0, cid: c.cid, cbid: c.cbid, minus: c.minus };
                                 const validQty = await this.ctx.service.stageChangeFinal.getChangeBillsValidQty(c.cbid);
                                 ncs.qty = validQty >= c.qty ? c.qty : validQty;
                                 insertChangeData.push(ncs);
-                                nps.qc_qty = await this.ctx.helper.add(nps.qc_qty, ncs.qty);
+                                if (!ncs.minus) nps.qc_qty = await this.ctx.helper.add(nps.qc_qty, ncs.qty);
                             }
                         }
                         nbs.contract_qty = this.ctx.helper.add(nbs.contract_qty, nps.contract_qty);
@@ -130,11 +130,11 @@ module.exports = app => {
                     if (d.change) {
                         for (const c of d.change) {
                             if (!c.qty) continue;
-                            const ncs = { tid: stage.tid, sid: stage.id, lid: d.id, pid: -1, stimes: 1, sorder: 0, cid: c.cid, cbid: c.cbid };
+                            const ncs = { tid: stage.tid, sid: stage.id, lid: d.id, pid: -1, stimes: 1, sorder: 0, cid: c.cid, cbid: c.cbid, minus: c.minus };
                             const validQty = await this.ctx.service.stageChangeFinal.getChangeBillsValidQty(c.cbid);
                             ncs.qty = validQty >= c.qty ? c.qty : validQty;
                             insertChangeData.push(ncs);
-                            nbs.qc_qty = await this.ctx.helper.add(nbs.qc_qty, ncs.qty);
+                            if (!ncs.minus) nbs.qc_qty = await this.ctx.helper.add(nbs.qc_qty, ncs.qty);
                         }
                     }
                     nbs.qc_tp = this.ctx.helper.mul(nbs.qc_qty, b.unit_price, decimal.tp);

Разница между файлами не показана из-за своего большого размера
+ 764 - 763
app/view/change/information_modal.ejs


+ 1 - 1
app/view/report/index_sign.ejs

@@ -481,7 +481,7 @@
                                     srcBytes: result2,
                                     certEncode: res.certCode,
                                     selMode: 1,
-                                    sealImageEncode: base64Set(netcaSignData.sign_base64),
+                                    sealImageEncode: netcaSignData.sign_base64,
                                     revInfoIncludeFlag: false,
                                     SignPosition: {
                                         startPage: 1,

+ 6 - 0
builder_report_index_define.js

@@ -2658,14 +2658,20 @@ const budget = {
 
             { name: '估算-项目节-数量1', field: 'gu_dgn_qty1', type: dataType.currency },
             { name: '估算-项目节-数量2', field: 'gu_dgn_qty2', type: dataType.currency },
+            { name: '估算-数量1/数量2', field: 'gu_dgn_qty', type: dataType.currency },
+            { name: '估算-经济指标', field: 'gu_dgn_price', type: dataType.currency },
             { name: '估算-金额', field: 'gu_tp', type: dataType.currency },
 
             { name: '概算-项目节-数量1', field: 'gai_dgn_qty1', type: dataType.currency },
             { name: '概算-项目节-数量2', field: 'gai_dgn_qty2', type: dataType.currency },
+            { name: '概算-数量1/数量2', field: 'gai_dgn_qty', type: dataType.currency },
+            { name: '概算-经济指标', field: 'gai_dgn_price', type: dataType.currency },
             { name: '概算-金额', field: 'gai_tp', type: dataType.currency },
 
             { name: '预算-项目节-数量1', field: 'yu_dgn_qty1', type: dataType.currency },
             { name: '预算-项目节-数量2', field: 'yu_dgn_qty2', type: dataType.currency },
+            { name: '预算-数量1/数量2', field: 'yu_dgn_qty', type: dataType.currency },
+            { name: '预算-经济指标', field: 'yu_dgn_price', type: dataType.currency },
             { name: '预算-金额', field: 'yu_tp', type: dataType.currency },
 
             { name: '决算-台账-项目节-数量1', field: 'dgn_qty1', type: dataType.currency },

+ 1 - 1
config/web.js

@@ -329,7 +329,7 @@ const JsFiles = {
                     '/public/js/stage_im.js',
                     '/public/js/shares/tenders2tree.js',
                     '/public/js/shares/tender_select.js',
-                    '/public/js/shares/stage_excel.js',
+                    // '/public/js/shares/stage_excel.js',
                     '/public/js/ledger_check.js',
                     '/public/js/stage.js',
                     '/public/js/stage_audit.js',

+ 11 - 0
sql/update.sql

@@ -35,12 +35,18 @@ CREATE TABLE `zh_budget_final` (
   `unit` varchar(15) CHARACTER SET utf8 NOT NULL DEFAULT '' COMMENT '单位',
   `gu_dgn_qty1` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '估算-设计数量1',
   `gu_dgn_qty2` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '估算-设计数量1',
+  `gu_dgn_qty` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '估算-设计数量1/设计数量2',
+  `gu_dgn_price` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '估算-经济指标',
   `gu_tp` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '估算-金额',
   `gai_dgn_qty1` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '概算-设计数量1',
   `gai_dgn_qty2` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '概算-设计数量1',
+  `gai_dgn_qty` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '概算-设计数量1/设计数量2',
+  `gai_dgn_price` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '概算-经济指标',
   `gai_tp` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '概算-金额',
   `yu_dgn_qty1` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '预算-设计数量1',
   `yu_dgn_qty2` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '预算-设计数量1',
+  `yu_dgn_qty` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '预算-设计数量1/设计数量2',
+  `yu_dgn_price` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '预算-经济指标',
   `yu_tp` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '预算-金额',
   `dgn_qty1` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '决算-台账-设计数量1',
   `dgn_qty2` decimal(24,8) NOT NULL DEFAULT '0.00000000' COMMENT '决算-台账-设计数量1',
@@ -99,3 +105,8 @@ Update zh_stage_change_final scf Join zh_stage s on scf.sid = s.id Set scf.sorde
 ALTER TABLE `zh_change` ADD `order_by` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '清单排序规则,默认按清单编号排(0),自定义排序(1)' AFTER `is_revise`;
 ALTER TABLE `zh_change_audit_list` ADD `order` INT NULL DEFAULT NULL COMMENT '排序序号(自定义规则时使用)' AFTER `spamount`;
 
+ALTER TABLE `zh_stage_change`
+ADD COLUMN `minus`  tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否负变更' AFTER `qty`;
+
+ALTER TABLE `zh_stage_change_final`
+ADD COLUMN `minus`  tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否负变更' AFTER `qty`;