소스 검색

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

laiguoran 3 년 전
부모
커밋
fd6df9031b
7개의 변경된 파일168개의 추가작업 그리고 72개의 파일을 삭제
  1. 4 0
      app/controller/stage_controller.js
  2. 118 33
      app/lib/analysis_excel.js
  3. 1 1
      app/public/js/stage.js
  4. 35 33
      app/service/stage_change.js
  5. 1 1
      app/service/stage_change_final.js
  6. 4 4
      app/service/stage_stash.js
  7. 5 0
      sql/update.sql

+ 4 - 0
app/controller/stage_controller.js

@@ -2077,6 +2077,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 +2104,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 };

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

@@ -502,7 +502,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 });
                     }
                 }
                 // 提交数据到后端

+ 35 - 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.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.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 });

+ 1 - 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);

+ 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);

+ 5 - 0
sql/update.sql

@@ -99,3 +99,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`;