Преглед изворни кода

附属工程量明细相关

MaiXinRong пре 20 часа
родитељ
комит
4fb218aed8

+ 42 - 26
app/controller/ledger_controller.js

@@ -366,7 +366,7 @@ module.exports = app => {
 
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = this.ajaxErrorBody(err);
             }
 
@@ -394,7 +394,7 @@ module.exports = app => {
                 }
                 responseData.data = await ctx.service.ledger.locateNode(tenderId, data.id);
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 responseData.err = 1;
                 responseData.msg = err;
             }
@@ -426,7 +426,7 @@ module.exports = app => {
                 const expandData = await ctx.service.ledger.getPosterityByParentId(tenderId, data.id);
                 responseData.data = { expand: expandData };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 responseData.err = 1;
                 responseData.msg = err;
             }
@@ -458,6 +458,9 @@ module.exports = app => {
                 const ancillaryGclData = this.ctx.tender.data.measure_type === measureType.tz.value
                     ? await ctx.service.ancillaryGcl.getAllDataByCondition({ where: { tid: ctx.tender.id } })
                     : [];
+                const ancGclDetailData = this.ctx.tender.data.measure_type === measureType.tz.value
+                    ? await ctx.service.ancillaryGclDetail.getAllDataByCondition({ where: { tid: ctx.tender.id } })
+                    : [];
                 if (this.ctx.tender.data.measure_type === measureType.tz.value) {
                     const calcTemplate = await ctx.service.ledgerExtra.getCalcTemplateData(ctx.tender.id);
                     this.ctx.helper.assignRelaData(ledgerData, [
@@ -471,12 +474,12 @@ module.exports = app => {
                 const ledgerTemplates = await this.ctx.service.ledgerTemplate.getAllTemplate(this.ctx.session.sessionProject.id);
                 ctx.body = {
                     err: 0, msg: '', data: {
-                        bills: ledgerData, pos: posData, ancGcl: ancillaryGclData, posCalcDetail: posCalcDetailData,
+                        bills: ledgerData, pos: posData, ancGcl: ancillaryGclData, posCalcDetail: posCalcDetailData, ancGclDetail: ancGclDetailData,
                         tags: ledgerTags, ledgerTemplates,
                     }
                 };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: [] };
             }
         }
@@ -501,7 +504,7 @@ module.exports = app => {
                 ], this.ctx.tender.info.decimal);
                 ctx.body = { err: 0, msg: '', data: checkData.checkResult };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = this.ajaxErrorBody(err, '检查数据错误');
             }
         }
@@ -513,7 +516,20 @@ module.exports = app => {
                 const responseData = await ctx.service.ancillaryGcl.updateDatas(data);
                 ctx.body = { err: 0, msg: '', data: responseData };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
+                ctx.body = { err: 1, msg: err.toString(), data: null };
+            }
+        }
+
+
+        async ancGclDetailUpdate(ctx) {
+            try {
+                await this.checkMeasureType(measureType.tz.value);
+                const data = JSON.parse(ctx.request.body.data);;
+                const responseData = await ctx.service.ancillaryGclDetail.updateDatas(data);
+                ctx.body = { err: 0, msg: '', data: responseData };
+            } catch (err) {
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: null };
             }
         }
@@ -525,7 +541,7 @@ module.exports = app => {
                 const responseData = await ctx.service.posCalcDetail.updateDatas(data);
                 ctx.body = { err: 0, msg: '', data: responseData };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: null };
             }
         }
@@ -543,7 +559,7 @@ module.exports = app => {
                 const responseData = await ctx.service.pos.savePosData(data, ctx.tender.id);
                 ctx.body = { err: 0, msg: '', data: responseData };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: null };
             }
         }
@@ -560,7 +576,7 @@ module.exports = app => {
                 const result = await ctx.service.pos.pastePosData(data, ctx.tender.id);
                 ctx.body = { err: 0, msg: '', data: result };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: null };
             }
         }
@@ -590,7 +606,7 @@ module.exports = app => {
                 }
                 ctx.body = responseData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: null };
             }
         }
@@ -676,7 +692,7 @@ module.exports = app => {
         //         }
         //         ctx.body = responseData;
         //     } catch (err) {
-        //         this.log(err);
+        //         ctx.log(err);
         //         // 失败需要消耗掉stream 以防卡死
         //         if (stream) await sendToWormhole(stream);
         //         ctx.body = {err: 1, msg: err.toString(), data: null};
@@ -699,7 +715,7 @@ module.exports = app => {
                 const ledgerData = await ctx.service.ledger.getData(ctx.tender.id);
                 ctx.body = { err: 0, msg: '', data: { bills: ledgerData } };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: null };
             }
         }
@@ -713,7 +729,7 @@ module.exports = app => {
                 const ledgerData = await ctx.service.ledger.getData(ctx.tender.id);
                 ctx.body = { err: 0, msg: '', data: { bills: ledgerData } };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: null };
             }
         }
@@ -741,7 +757,7 @@ module.exports = app => {
                         fs.unlinkSync(fileName);
                     }
                 } catch (err) {
-                    this.log(err);
+                    ctx.log(err);
                     this.setMessage(err.toString(), this.messageType.ERROR);
                 }
             }
@@ -764,7 +780,7 @@ module.exports = app => {
                 };
                 await this.layout('ledger/bwtz.ejs', renderData);
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.redirect(ctx.request.header.referer);
             }
         }
@@ -786,7 +802,7 @@ module.exports = app => {
                 // }
                 ctx.body = { err: 0, msg: '', data: result };
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = this.ajaxErrorBody(err, '加载合同支付数据错误');
             }
         }
@@ -806,7 +822,7 @@ module.exports = app => {
 
                 await this.layout('ledger/gather.ejs', renderData);
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 await this.redirect(ctx.request.header.referer);
             }
         }
@@ -850,7 +866,7 @@ module.exports = app => {
                     bills: billsData, pos: posData, ancGcl, dealBills, change, spec: {zlj: zlj, jrg: stdConst.jrg},
                 }};
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 ctx.body = { err: 1, msg: err.toString(), data: [] };
             }
         }
@@ -878,7 +894,7 @@ module.exports = app => {
                 await ctx.service.ledgerAudit.loadLedgerAuditViewData(tender);
                 ctx.body = {err: 0, msg: '', data: tender};
             } catch (error) {
-                this.log(error);
+                ctx.log(error);
                 ctx.body = { err: 1, msg: error.toString(), data: null };
             }
         }
@@ -934,7 +950,7 @@ module.exports = app => {
                 }
                 responseData.data = files;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 // 失败需要消耗掉stream 以防卡死
                 if (stream) {
                     await sendToWormhole(stream);
@@ -979,7 +995,7 @@ module.exports = app => {
                         throw '不存在该文件';
                     }
                 } catch (err) {
-                    this.log(err);
+                    ctx.log(err);
                     this.setMessage(err.toString(), this.messageType.ERROR);
                 }
             }
@@ -1007,7 +1023,7 @@ module.exports = app => {
                         fileInfo.filepath && (responseData.data = { filepath });
                     }
                 } catch (error) {
-                    this.log(error);
+                    ctx.log(error);
                     this.setMessage(error.toString(), this.messageType.ERROR);
                     responseData.err = 1;
                     responseData.msg = error.toString();
@@ -1099,7 +1115,7 @@ module.exports = app => {
                 attData.in_time = moment(attData.in_time * 1000).format('YYYY-MM-DD');
                 responseData.data = attData;
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 // 失败需要消耗掉stream 以防卡死
                 if (stream) {
                     await sendToWormhole(stream);
@@ -1151,7 +1167,7 @@ module.exports = app => {
                 });
                 // fs的错误不能被try catch捕捉
                 readStream.on('error', err => {
-                    this.log(err);
+                    ctx.log(err);
                     if (fs.existsSync(path.resolve(this.app.baseDir, zipPath))) {
                         fs.unlinkSync(path.resolve(this.app.baseDir, zipPath));
                     }
@@ -1160,7 +1176,7 @@ module.exports = app => {
                     ctx.body = responseData;
                 });
             } catch (err) {
-                this.log(err);
+                ctx.log(err);
                 if (fs.existsSync(path.resolve(this.app.baseDir, zipPath))) {
                     fs.unlinkSync(path.resolve(this.app.baseDir, zipPath));
                 }

+ 125 - 18
app/public/js/ledger.js

@@ -553,8 +553,8 @@ $(document).ready(function() {
                 detail.updateDatas(result.detail);
                 reloadCurDetailData();
                 if (result.ancGcl) {
-                    ancGcl.updateDatas(result.ancGcl);
-                    // todo 刷新附属工程量
+                    ancGcl.updateDatas({ update: result.ancGcl });
+                    ancGclObj.loadCurAncillaryGcl();
                 }
             },
             baseOpr: function (type, addCount = 1) {
@@ -569,10 +569,10 @@ $(document).ready(function() {
                 const row = sel[0].row, count = sel[0].rowCount;
                 const first = detailRange[row];
                 if (type === 'insert') {
-                    const node = SpreadJsObj.getSelectObject(posSheet);
+                    const node = SpreadJsObj.getSelectObject(ancGclSheet);
                     data.add = [];
                     for (let i = 1; i <= addCount; i++) {
-                        data.add.push({ lid: node.lid, pid: node.id, pcd_order: detailRange.length + i });
+                        data.add.push({ lid: node.lid, pid: node.pid, ag_id: node.id, agd_order: detailRange.length + i });
                     }
                     if (first) data.select = first.id;
                 } else if (type === 'delete') {
@@ -617,7 +617,7 @@ $(document).ready(function() {
                     if (data.update <= 1) return;
                 }
 
-                postData('/tender/' + getTenderId() + '/anc-gcl-calc/update', data, function(result) {
+                postData('/tender/' + getTenderId() + '/anc-gcl-detail/update', data, function(result) {
                     ctrlObj.afterPostData(result);
                     if (type !== 'delete') SpreadJsObj.locateData(sheet, first);
                 });
@@ -636,9 +636,9 @@ $(document).ready(function() {
                 const orgText = detailData ? detailData[col.field] : '', newText = trimInvalidChar(info.editingText);
                 if (orgText === newText || (!orgText && !newText)) return;
 
-                const pos = ctrlObj.posNode;
-                if (!pos) {
-                    toastr.error('数据错误,请选择计量单元后再试');
+                const ancGcl = ctrlObj.ancGclNode;
+                if (!ancGcl) {
+                    toastr.error('数据错误,请选择附属工程量后再试');
                     SpreadJsObj.reLoadRowData(info.sheet, info.row);
                     return;
                 }
@@ -666,7 +666,7 @@ $(document).ready(function() {
                 } else {
                     const sortData = info.sheet.zh_data;
                     const order = (!sortData || sortData.length === 0) ? 1 : Math.max(sortData[sortData.length - 1].pcd_order + 1, sortData.length + 1);
-                    const addData = { lid: pos.lid, pid: pos.id, pcd_order: order };
+                    const addData = { lid: ancGcl.lid, pid: ancGcl.pid, ag_id: ancGcl.id, agd_order: order };
                     if (col.type === 'Number') {
                         const num = _.toNumber(newText);
                         if (!_.isFinite(num)) {
@@ -685,7 +685,7 @@ $(document).ready(function() {
                     }
                     data.add = [addData];
                 }
-                postData('/tender/' + getTenderId() + '/pos-calc/update', data, function (result) {
+                postData('/tender/' + getTenderId() + '/anc-gcl-detail/update', data, function (result) {
                     ctrlObj.afterPostData(result);
                 }, function () {
                     SpreadJsObj.reLoadRowData(info.sheet, info.row);
@@ -718,7 +718,7 @@ $(document).ready(function() {
                 }
                 if (data.update.length === 0) return;
 
-                postData('/tender/' + getTenderId() + '/pos-calc/update', data, function (result) {
+                postData('/tender/' + getTenderId() + '/anc-gcl-detail/update', data, function (result) {
                     ctrlObj.afterPostData(result);
                 }, function () {
                     SpreadJsObj.reLoadRowData(info.sheet, info.row);
@@ -726,8 +726,8 @@ $(document).ready(function() {
             },
             clipboardPasting: function(e, info) {
                 info.cancel = true;
-                const relaPos = SpreadJsObj.getSelectObject(posSheet);
-                if (!relaPos) {
+                const relaAncGcl = SpreadJsObj.getSelectObject(ancGclSheet);
+                if (!relaAncGcl) {
                     toastr.error('数据错误,请选择计量单元后再试');
                     SpreadJsObj.reLoadRowData(info.sheet, info.row);
                     return;
@@ -771,14 +771,14 @@ $(document).ready(function() {
                         data.update.push(updateData);
                     } else {
                         if (!data.add) data.add = [];
-                        const addData = { lid: relaPos.lid, pid: relaPos.id, pcd_order: curRow + 1};
+                        const addData = { lid: relaAncGcl.lid, pid: relaAncGcl.pid, ag_id: relaAncGcl.id, agd_order: curRow + 1};
                         analysisData(pasteData[iRow], addData);
                         data.add.push(addData);
                     }
                 }
                 if ((!data.update || data.update.length === 0) && (!data.add || data.add.length === 0)) return;
 
-                postData('/tender/' + getTenderId() + '/pos-calc/update', data, function (result) {
+                postData('/tender/' + getTenderId() + '/anc-gcl-detail/update', data, function (result) {
                     ctrlObj.afterPostData(result);
                 }, function () {
                     SpreadJsObj.reLoadRowData(info.sheet, info.row);
@@ -1949,7 +1949,20 @@ $(document).ready(function() {
                 }
             }
             return copyBlockList;
-        }
+        },
+        removeCalcTemplate: function(node) {
+            const billsUpdateData = {postType: 'extra', postData: { id: node.id, tender_id: node.tender_id, ledger_id: node.ledger_id, calc_template: '' }};
+            postData(window.location.pathname + '/update', billsUpdateData, function (result) {
+                const refreshNode = ledgerTree.loadPostData(result);
+                treeOperationObj.refreshTree(ledgerSheet, refreshNode);
+                if (result.pos) {
+                    pos.updateDatas(result.pos);
+                    posOperationObj.loadCurPosData(false);
+                }
+                posCalcDetail.detail.removeDatasByTopId(node.id);
+                posCalcDetail.loadCurDetailData();
+            });
+        },
     };
     const ledgerTemplate = $.ledger_template({
         selector: '#ledger-template',
@@ -2383,11 +2396,20 @@ $(document).ready(function() {
             disabled: function(key, opt) {
                 const node = SpreadJsObj.getSelectObject(ledgerSheet);
                 return !node || !node.b_code;
+            }
+        };
+        billsContextMenuOptions.items.removeCalcTmpl = {
+            name: '移除计算模板',
+            callback: function(key, opt) {
+                const node = SpreadJsObj.getSelectObject(ledgerSheet);
+                treeOperationObj.removeCalcTemplate(node);
             },
-            visible: function(key, opt) {
-                return !readOnly;
+            disabled: function(key, opt) {
+                const node = SpreadJsObj.getSelectObject(ledgerSheet);
+                return !node || !node.b_code || !node.calc_template;
             }
         };
+        billsContextMenuOptions.items.calcTmplSpr = '----';
         billsContextMenuOptions.items.batchInsert = {
             name: '批量插入',
             type: 'batchInsert',
@@ -3899,6 +3921,46 @@ $(document).ready(function() {
         selectionChanged: function(e, info) {
             ancGclDetail.loadCurDetailData();
         },
+        removeCalcTemplate: function(node) {
+            const ancGclUpdateData = { calcTmpl: { id: node.id, calc_template: '' } };
+            postData('/tender/' + getTenderId() + '/anc-gcl/update', ancGclUpdateData, function(result) {
+                ancGcl.updateDatas(result);
+                ancGclObj.loadCurAncillaryGcl();
+                ancGclDetail.detail.updateDatas({ update: result.detail });
+                ancGclDetail.reloadCurDetailData();
+            });
+        },
+        getBlockData: function() {
+            const copyBlockList = [];
+            const sheet = ancGclSheet;
+            const sel = sheet.getSelections()[0];
+            let iRow = sel.row;
+            while (iRow < sel.row + sel.rowCount) {
+                const p = sheet.zh_data[iRow];
+                if (!p) break;
+                copyBlockList.push(p);
+                if (p.calc_template) {
+                    const detailRange = ancGclDetail.detail.getPartData(p.id);
+                    p.calcDetail = detailRange;
+                }
+                iRow++;
+            }
+            return copyBlockList;
+        },
+        pasteBlock: function(copyInfo) {
+            const posNode = SpreadJsObj.getSelectObject(posSheet);
+            if (!posNode) {
+                toastr.error('数据错误,请选择计量单元后再试');
+                SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                return;
+            }
+            const data = { pasteBlock: { pid: posNode.id, tid: copyInfo.tid, block: copyInfo.block } };
+            postData('/tender/' + getTenderId() + '/anc-gcl/update', data, function (result) {
+                ancGcl.updateDatas(result);
+                if (result.details) ancGclDetail.detail.updateDatas(result.details);
+                ancGclObj.loadCurAncillaryGcl();
+            });
+        }
     };
     ancGclSpread.bind(spreadNS.Events.SelectionChanged, ancGclObj.selectionChanged);
     if (!readOnly) {
@@ -3975,6 +4037,48 @@ $(document).ready(function() {
                         const node = SpreadJsObj.getSelectObject(ancGclSheet);
                         return !node;
                     }
+                },
+                removeCalcTemplate: {
+                    name: '移除计算模板',
+                    callback: function(key, opt) {
+                        const node = SpreadJsObj.getSelectObject(ancGclSheet);
+                        ancGclObj.removeCalcTemplate(node);
+                    },
+                    disabled: function(key, opt) {
+                        const node = SpreadJsObj.getSelectObject(ancGclSheet);
+                        return !node || !node.calc_template;
+                    }
+                },
+                calcTmplSpr: '----',
+                copyBlock: {
+                    name: '复制整块',
+                    callback: function(key, opt) {
+                        ancGclObj.block = [];
+                        const copyBlockList = ancGclObj.getBlockData();
+                        setLocalCache(copyBlockTag, JSON.stringify({ block: copyBlockList, tag: 'ancGcl' }));
+                    },
+                    disabled: function(key, opt) {
+                        const node = SpreadJsObj.getSelectObject(ancGclSheet);
+                        return !node;
+                    }
+                },
+                pasteBlock: {
+                    name: '粘贴整块',
+                    callback: function(key, opt) {
+                        const copyInfo = JSON.parse(getLocalCache(copyBlockTag));
+                        if (copyInfo.block.length > 0) {
+                            ancGclObj.pasteBlock(copyInfo);
+                        } else {
+                            document.execCommand('paste');
+                        }
+                    },
+                    disabled: function(key, opt) {
+                        const pos = SpreadJsObj.getSelectObject(posSheet);
+                        if (!pos) return true;
+
+                        const copyInfo = JSON.parse(getLocalCache(copyBlockTag));
+                        return !(copyInfo && copyInfo.block && copyInfo.block.length > 0 && copyInfo.tag === 'ancGcl');
+                    }
                 }
             }
         });
@@ -4017,6 +4121,9 @@ $(document).ready(function() {
 
         ancGclObj.loadCurAncillaryGcl();
         SpreadJsObj.resetTopAndSelect(ancGclSheet);
+        ancGclDetail.detail.loadDatas(data.ancGclDetail);
+        ancGclDetail.loadCurDetailData();
+        SpreadJsObj.resetTopAndSelect(ancGclDetail.sheet);
 
         posCalcDetail.detail.loadDatas(data.posCalcDetail);
         posCalcDetail.loadCurDetailData();

+ 2 - 1
app/router.js

@@ -681,9 +681,10 @@ module.exports = app => {
     app.post('/tender/:id/ledger/dsk', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.importDsk');
     app.get('/tender/:id/ledger/download/:file', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.download');
     app.post('/tender/:id/anc-gcl/update', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.ancGclUpdate');
-    app.post('/tender/:id/pos-calc/update', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.posCalcUpdate');
+    app.post('/tender/:id/anc-gcl-detail/update', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.ancGclDetailUpdate');
     app.post('/tender/:id/pos/update', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.posUpdate');
     app.post('/tender/:id/pos/paste', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.posPaste');
+    app.post('/tender/:id/pos-calc/update', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.posCalcUpdate');
     app.post('/tender/:id/ledger/deal2sgfh', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.deal2sgfh');
     app.post('/tender/:id/ledger/sgfh2deal', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.sgfh2deal');
     app.post('/tender/:id/ledger/check', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.check');

+ 59 - 2
app/service/ancillary_gcl.js

@@ -144,7 +144,7 @@ module.exports = app => {
                         ud.quantity = this.ctx.helper.round(quantity, qtyDecimal);
                     }
                 } else {
-                    await this.ctx.service.ancillaryGcl.deleteAncGclPartData(conn, orgDatas[0].tid, uDatas.map(x => { return x.id; }));
+                    await this.ctx.service.ancillaryGclDetail.deleteAncGclPartData(conn, orgDatas[0].tid, uDatas.map(x => { return x.id; }));
                 }
                 await conn.updateRows(this.tableName, uDatas);
                 await conn.commit();
@@ -155,8 +155,62 @@ module.exports = app => {
                 throw '修改计算模板失败';
             }
         }
+        async _pasteBlock(data) {
+            if (!(data.block instanceof Array)) throw '提交数据错误';
+
+            const qtyDecimal = this.ctx.tender.info.decimal.qty;
+            const user_id = this.ctx.session.sessionUser.accountId;
+            const pos = await this.ctx.service.pos.getDataById(data.pid);
+            const existAncGcl = await this.getAllDataByCondition({ where : { pid: data.pid }, orders: [['g_order', 'DESC']]});
+            const maxOrder = existAncGcl.length > 0 ? existAncGcl[0].g_order : 0;
+
+            const insertAncGcl = [], insertDetail = [];
+            for (const [i, b] of data.block.entries()) {
+                const nig = {
+                    id: this.uuid.v4(), tid: this.ctx.tender.id,
+                    add_user_id: user_id, update_user_id: user_id,
+                    lid: pos.lid, pid: pos.id, g_order: maxOrder + i + 1,
+                    is_aux: b.is_aux || 0, name: b.name || '', unit: b.unit || '',
+                    drawing_code: b.drawing_code || '', memo: b.memo || '',
+                    quantity: b.quantity || 0, expr: b.expr || '', calc_template: b.calc_template || ''
+                };
+                insertAncGcl.push(nig);
+                if (!b.calc_template) continue;
+
+                let sumQty = 0;
+                for (const cd of b.calcDetail) {
+                    const newDetail = {
+                        id: this.uuid.v4(), tid: this.ctx.tender.id, lid: pos.lid, pid: pos.id, ag_id: nig.id,
+                        create_user_id: user_id, update_user_id: user_id,
+                        agd_order: cd.agd_order,
+                        str1 : cd.str1 || '', str2 : cd.str1 || '', str3 : cd.str1 || '', str4 : cd.str1 || '',
+                        num_a : cd.num_a || 0, num_b : cd.num_b || 0, num_c : cd.num_c || 0, num_d : cd.num_d || 0,
+                        num_e : cd.num_e || 0, num_f : cd.num_f || 0, num_g : cd.num_g || 0, num_h : cd.num_h || 0,
+                        num_i : cd.num_i || 0, num_j : cd.num_j || 0, num_k : cd.num_k || 0, num_l : cd.num_l || 0,
+                        num_m : cd.num_m || 0, num_n : cd.num_n || 0, num_o : cd.num_o || 0, num_p : cd.num_p || 0,
+                        num_q : cd.num_q || 0, num_r : cd.num_r || 0, num_s : cd.num_s || 0, num_t : cd.num_t || 0,
+                        num_u : cd.num_u || 0,
+                        qty: cd.qty || 0, expr: cd.expr || 0, spec: cd.spec || ''
+                    };
+                    sumQty = this.ctx.helper.add(sumQty, newDetail.qty);
+                    insertDetail.push(newDetail);
+                }
+                nig.quantity = this.ctx.helper.round(sumQty, qtyDecimal);
+            }
+
+            const transaction = await this.db.beginTransaction();
+            try {
+                await transaction.insert(this.tableName, insertAncGcl);
+                if (insertDetail.length > 0) await transaction.insert(this.ctx.service.ancillaryGclDetail.tableName, insertDetail);
+                await transaction.commit();
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+            return [ insertAncGcl, { add: insertDetail }];
+        }
         async updateDatas(data) {
-            const result = {add: [], del: [], update: [], details: []};
+            const result = { add: [], del: [], update: [], details: null };
             try {
                 if (data.add) {
                     result.add = await this._addDatas(data.add);
@@ -170,6 +224,9 @@ module.exports = app => {
                 if (data.calcTmpl) {
                     [result.update, result.details] = await this._setCalcTemplate(data.calcTmpl);
                 }
+                if (data.pasteBlock) {
+                    [result.add, result.details] = await this._pasteBlock(data.pasteBlock);
+                }
                 return result;
             } catch (err) {
                 if (err.stack) {

+ 47 - 80
app/service/ancillary_gcl_detail.js

@@ -97,42 +97,21 @@ module.exports = app => {
         // --------------------------------------------
 
         async _getAncGclUpdateData(data, ag_id, calc = true) {
-            if (!calc) return [null, null];
-
+            if (!calc) return null;
             try {
-                const ancGclData = await this.ctx.service.ancillaryGcl.getDataById(ag_id);
-                const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, ledgerData.unit);
-                const posDatas = await this.ctx.service.pos.getAllDataByCondition({ where: { lid } });
-                const detailDatas = await this.getAllDataByCondition({ columns: ['id', 'lid', 'pid', 'qty'], where: { pid } });
+                const detailDatas = await this.getAllDataByCondition({ columns: ['id', 'ag_id', 'qty'], where: { ag_id } });
 
-                let sumPosQty = 0;
+                const ancGclUpdate = { id: ag_id, quantity: 0 };
                 for (const d of data) {
-                    sumPosQty = this.ctx.helper.add(d.qty, sumPosQty);
+                    ancGclUpdate.quantity = this.ctx.helper.add(d.qty, ancGclUpdate.quantity);
                 }
                 for (const d of detailDatas) {
                     if (data.findIndex(x => { return x.id === d.id; }) >= 0) continue;
-                    sumPosQty = this.ctx.helper.add(d.qty, sumPosQty);
-                }
-                const op = posDatas.find(x => { return x.id === pid; });
-                if (!op) throw '所属计量单元不存在,请刷新页面后再试';
-                const ppd = { id: op.id, sgfh_qty: this.ctx.helper.round(sumPosQty, precision.value) };
-                ppd.quantity = this.ctx.helper.sum([ppd.sgfh_qty, op.sjcl_qty, op.qtcl_qty]);
-
-                let sumBillsQty = 0;
-                for (const pd of posDatas) {
-                    if (pd.id === pid) {
-                        sumBillsQty = this.ctx.helper.add(sumBillsQty, ppd.sgfh_qty);
-                    } else {
-                        sumBillsQty = this.ctx.helper.add(sumBillsQty, pd.sgfh_qty);
-                    }
+                    ancGclUpdate.quantity = this.ctx.helper.add(d.qty, ancGclUpdate.quantity);
                 }
-                const bpd = { id: ledgerData.id, sgfh_qty: sumBillsQty };
-                bpd.sgfh_tp = this.ctx.helper.mul(bpd.sgfh_qty, ledgerData.unit_price, this.ctx.tender.info.decimal.tp);
-                bpd.quantity = this.ctx.helper.sum([bpd.sgfh_qty, ledgerData.sjcl_qty, ledgerData.qtcl_qty]);
-                bpd.total_price = this.ctx.helper.mul(bpd.quantity, ledgerData.unit_price, this.ctx.tender.info.decimal.tp);
-                return [ppd, bpd];
+                return ancGclUpdate;
             } catch (err) {
-                return [null, null];
+                return null;
             }
         }
 
@@ -140,35 +119,35 @@ module.exports = app => {
             const user_id = this.ctx.session.sessionUser.accountId;
 
             const datas = data instanceof Array ? data : [data];
-            const le = await this.ctx.service.ledgerExtra.getDataById(datas[0].lid);
-            if (!le.calc_template) throw '未定义计算模板,请先在清单处选择计算模板';
-            const calcTemplate = await this.ctx.service.calcTmpl.getTemplate(le.calc_template);
+            const ancGcl = await this.ctx.service.ancillaryGcl.getDataById(datas[0].ag_id);
+            if (!ancGcl.calc_template) throw '未定义计算模板,请先在附属工程量选择计算模板';
+            const calcTemplate = await this.ctx.service.calcTmpl.getTemplate(ancGcl.calc_template);
             if (!calcTemplate) throw '计算模板不存在';
-            const posDetail = await this.getAllDataByCondition({ where: { tid: this.ctx.tender.id, pid: datas[0].pid }, orders: [['pcd_order', 'ASC']] });
-            const selectIndex = selectId ? posDetail.findIndex(x => { return x.id === selectId; }) : -1;
+            const details = await this.getAllDataByCondition({ where: { tid: this.ctx.tender.id, pid: datas[0].pid }, orders: [['agd_order', 'ASC']] });
+            const selectIndex = selectId ? details.findIndex(x => { return x.id === selectId; }) : -1;
             if (selectId && selectIndex < 0) throw '选择的数据不存在';
             const startOrder = selectId
-                ? (selectIndex > 0 ? posDetail[selectIndex - 1].pcd_order : 0)
-                : (posDetail.length > 0 ? posDetail[posDetail.length - 1].pcd_order : 0);
+                ? (selectIndex > 0 ? details[selectIndex - 1].agd_order : 0)
+                : (details.length > 0 ? details[details.length - 1].agd_order : 0);
 
             const insertData = [], updateData = [];
             let isCalc = false;
             for (const [i, d] of datas.entries()) {
-                if (!d.lid || !d.pid || !d.pcd_order) throw '新增其他数据,提交的数据错误';
+                if (!d.lid || !d.pid || !d.ag_id || !d.agd_order) throw '新增其他数据,提交的数据错误';
                 const nd = {
                     id: this.uuid.v4(), tid: this.ctx.tender.id,
                     create_user_id: user_id, update_user_id: user_id,
-                    lid: d.lid, pid: d.pid, pcd_order: startOrder + i + 1,
+                    lid: d.lid, pid: d.pid, ag_id: d.ag_id, agd_order: startOrder + i + 1,
                 };
                 if (this._loadDataAndCalc(nd, d, {}, calcTemplate)) isCalc = true;
                 insertData.push(nd);
             }
-            const [posUpdate, billsUpdate] = await this._getBillsPosUpdateData(insertData, insertData[0].pid, insertData[0].lid, isCalc);
+            const gclUpdate = await this._getAncGclUpdateData(insertData, insertData[0].ag_id, isCalc);
             if (selectIndex >= 0) {
-                const maxOrder = insertData[insertData.length - 1].pcd_order;
-                for (const p of posDetail) {
-                    if (p.pcd_order > startOrder) {
-                        updateData.push({ id: p.id, pcd_order: maxOrder + updateData.length + 1 });
+                const maxOrder = insertData[insertData.length - 1].agd_order;
+                for (const p of details) {
+                    if (p.agd_order > startOrder) {
+                        updateData.push({ id: p.id, agd_order: maxOrder + updateData.length + 1 });
                     }
                 }
             }
@@ -177,8 +156,7 @@ module.exports = app => {
             try {
                 await conn.insert(this.tableName, insertData);
                 if (updateData.length > 0) await conn.updateRows(this.tableName, updateData);
-                if (posUpdate) await conn.update(this.ctx.service.pos.tableName, posUpdate);
-                if (billsUpdate) await conn.update(this.ctx.service.ledger.tableName, billsUpdate);
+                if (gclUpdate) await conn.update(this.ctx.service.ancillaryGcl.tableName, gclUpdate);
                 await conn.commit();
             } catch(err) {
                 await conn.rollback();
@@ -187,42 +165,39 @@ module.exports = app => {
             const addData = await this.getAllDataByCondition({
                 where: { id: this.ctx.helper._.map(insertData, 'id') }
             });
-            const posData = isCalc ? await this.ctx.service.pos.getDataById(addData[0].pid) : null;
-            const ledgerData = isCalc ? await this.ctx.service.ledger.getDataById(addData[0].lid) : null;
-            return [addData, updateData, posData, ledgerData]
+            const gclUpdateData = isCalc ? await this.ctx.service.ancillaryGcl.getDataById(addData[0].ag_id) : null;
+            return [addData, updateData, gclUpdateData]
         }
         async _delDatas (data) {
             if (!data || data.length === 0) throw '提交数据错误';
             const orgDatas = await this.getAllDataByCondition({ where: { id: data } });
 
-            if (!orgDatas || orgDatas.length === 0) throw '删除的设计量明细不存在';
+            if (!orgDatas || orgDatas.length === 0) throw '删除的明细不存在';
 
-            let posDetail = await this.getAllDataByCondition({ where: { tid: orgDatas[0].tid, pid: orgDatas[0].pid } });
-            posDetail = posDetail.filter(pa => {
+            let details = await this.getAllDataByCondition({ where: { tid: orgDatas[0].tid, pid: orgDatas[0].pid } });
+            details = details.filter(pa => {
                 return data.indexOf(pa.id) < 0;
             });
-            posDetail.sort((x, y) => { return x.pcd_order - y.pcd_order; });
+            details.sort((x, y) => { return x.agd_order - y.agd_order; });
 
             const updateData = [];
-            posDetail.forEach((x, i) => {
-                if (x.pcd_order !== i + 1) updateData.push({ id: x.id, pcd_order: i + 1});
+            details.forEach((x, i) => {
+                if (x.agd_order !== i + 1) updateData.push({ id: x.id, agd_order: i + 1});
             });
-            const [posUpdate, billsUpdate] = await this._getBillsPosUpdateData(data.map(x => { return { id: x, qty: 0 }; }), orgDatas[0].pid, orgDatas[0].lid);
+            const gclUpdate = await this._getAncGclUpdateData(data.map(x => { return { id: x, qty: 0 }; }), orgDatas[0].ag_id);
 
             const conn = await this.db.beginTransaction();
             try {
                 await conn.delete(this.tableName, { id: data });
                 if (updateData.length > 0) await conn.updateRows(this.tableName, updateData);
-                if (posUpdate) await conn.update(this.ctx.service.pos.tableName, posUpdate);
-                if (billsUpdate) await conn.update(this.ctx.service.ledger.tableName, billsUpdate);
+                if (gclUpdate) await conn.update(this.ctx.service.ancillaryGcl.tableName, gclUpdate);
                 await conn.commit();
             } catch (err) {
                 await conn.rollback();
                 throw err;
             }
-            const posData = await this.ctx.service.pos.getDataById(orgDatas[0].pid);
-            const ledgerData = await this.ctx.service.ledger.getDataById(orgDatas[0].lid);
-            return [data, updateData, posData, ledgerData];
+            const ancGclData = await this.ctx.service.ancillaryGcl.getDataById(orgDatas[0].ag_id);
+            return [data, updateData, ancGclData];
         }
         async _updateDatas (data) {
             if (!data || data.length === 0) throw '提交数据错误';
@@ -232,11 +207,11 @@ module.exports = app => {
             const orgDatas = await this.getAllDataByCondition({
                 where: { id: this.ctx.helper._.map(datas, 'id') }
             });
-            if (!orgDatas || orgDatas.length === 0) throw '修改的设计量明细不存在';
+            if (!orgDatas || orgDatas.length === 0) throw '修改的明细不存在';
 
-            const le = await this.ctx.service.ledgerExtra.getDataById(orgDatas[0].lid);
-            if (!le.calc_template) throw '未定义计算模板,请先在清单处选择计算模板';
-            const calcTemplate = await this.ctx.service.calcTmpl.getTemplate(le.calc_template);
+            const ancGcl = await this.ctx.service.ancillaryGcl.getDataById(orgDatas[0].ag_id);
+            if (!ancGcl.calc_template) throw '未定义计算模板,请先在附属工程量选择计算模板';
+            const calcTemplate = await this.ctx.service.calcTmpl.getTemplate(ancGcl.calc_template);
             if (!calcTemplate) throw '计算模板不存在';
 
             const uDatas = [];
@@ -246,52 +221,44 @@ module.exports = app => {
                 if (!od) continue;
 
                 const nd = { id: od.id, update_user_id: user_id };
-                if (d.pcd_order) nd.pcd_order = d.pcd_order;
+                if (d.agd_order) nd.agd_order = d.agd_order;
                 if (this._loadDataAndCalc(nd, d, od, calcTemplate)) isCalc = true;
                 uDatas.push(nd);
             }
-            const [posUpdate, billsUpdate] = await this._getBillsPosUpdateData(uDatas, orgDatas[0].pid, orgDatas[0].lid, isCalc);
+            const gclUpdate = await this._getAncGclUpdateData(uDatas, orgDatas[0].ag_id, isCalc);
 
             if (uDatas.length > 0) {
                 const conn = await this.db.beginTransaction();
                 try {
                     await conn.updateRows(this.tableName, uDatas);
-                    if (posUpdate) await conn.update(this.ctx.service.pos.tableName, posUpdate);
-                    if (billsUpdate) await conn.update(this.ctx.service.ledger.tableName, billsUpdate);
+                    if (gclUpdate) await conn.update(this.ctx.service.ancillaryGcl.tableName, gclUpdate);
                     await conn.commit();
                 } catch (err) {
                     await conn.rollback();
                     throw err;
                 }
-                const posData = isCalc ? await this.ctx.service.pos.getDataById(orgDatas[0].pid) : null;
-                const ledgerData = isCalc ? await this.ctx.service.ledger.getDataById(orgDatas[0].lid) : null;
-                return [uDatas, posData, ledgerData];
+                return [uDatas, gclUpdate];
             } else {
                 return [];
             }
         }
         async updateDatas(data) {
-            const result = { detail: {add: [], del: [], update: []}, pos: null, bills: null };
+            const result = { detail: {add: [], del: [], update: []}, ancGcl: null};
             try {
                 if (data.add) {
-                    [result.detail.add, result.detail.update, result.pos, result.bills] = await this._addDatas(data.add, data.select);
+                    [result.detail.add, result.detail.update, result.ancGcl] = await this._addDatas(data.add, data.select);
                 }
                 if (data.update) {
                     const orgUpdate = result.detail.update;
-                    [result.detail.update, result.pos, result.bills] = await this._updateDatas(data.update);
+                    [result.detail.update, result.ancGcl] = await this._updateDatas(data.update);
                     if (orgUpdate.length > 0) result.detail.update.push(...orgUpdate);
                 }
                 if (data.del) {
-                    [result.detail.del, result.detail.update, result.pos, result.bills] = await this._delDatas(data.del);
+                    [result.detail.del, result.detail.update, result.ancGcl] = await this._delDatas(data.del);
                 }
                 return result;
             } catch (err) {
-                if (err.stack) {
-                    throw err;
-                } else {
-                    result.err = err.toString();
-                    return result;
-                }
+                throw err;
             }
         }
 

+ 6 - 2
app/service/ledger.js

@@ -881,8 +881,12 @@ module.exports = app => {
                 } else {
                     await conn.insert(this.service.ledgerExtra.tableName, { id: data.id, tid, calc_template: data.calc_template });
                 }
-                // 重算所有数据
-                const calc = await this.ctx.service.posCalcDetail.resetBillsCalcTemplate(conn, data.id, data.calc_template);
+                if (!data.calc_template) {
+                    await this.ctx.service.posCalcDetail.deleteBillsPartData(conn, tid, data.id);
+                    await this.ctx.service.posCalcDetail.removeBillsCalcTemplate(conn, data.id);
+                } else {
+                    await this.ctx.service.posCalcDetail.resetBillsCalcTemplate(conn, data.id, data.calc_template);
+                }
                 await conn.commit();
             } catch (err) {
                 await conn.rollback();

+ 22 - 0
app/service/pos_calc_detail.js

@@ -331,6 +331,28 @@ module.exports = app => {
             await transaction.update(this.ctx.service.ledger.tableName, ub);
             return detailUpdateDatas.length > 0 || posUpdateData.length > 0;
         }
+        async removeBillsCalcTemplate(transaction, lid) {
+            const user_id = this.ctx.session.sessionUser.accountId;
+
+            const ledgerData = await this.ctx.service.ledger.getDataById(lid);
+            const posDatas = await this.ctx.service.pos.getAllDataByCondition({ where: { lid } });
+
+            const posUpdateData = [];
+            let bQty = 0;
+            for (const p of posDatas) {
+                const up = { id: p.id, sgfh_qty: 0, sgfh_expr: '' };
+                up.quantity = this.ctx.helper.sum([up.sgfh_qty, p.sjcl_qty, p.qtcl_qty]);
+                posUpdateData.push(up);
+                bQty = this.ctx.helper.add(bQty, up.sgfh_qty);
+            }
+            const ub = { id: lid, sgfh_qty: bQty };
+            ub.sgfh_tp = this.ctx.helper.mul(ub.sgfh_qty, ledgerData.unit_price, this.ctx.tender.info.decimal.tp);
+            ub.quantity = this.ctx.helper.sum([ub.sgfh_qty, ledgerData.sjcl_qty, ledgerData.qtcl_qty]);
+            ub.total_price = this.ctx.helper.mul(ub.quantity, ledgerData.unit_price, this.ctx.tender.info.decimal.tp);
+
+            if (posUpdateData.length > 0) await transaction.updateRows(this.ctx.service.pos.tableName, posUpdateData);
+            await transaction.update(this.ctx.service.ledger.tableName, ub);
+        }
 
         async deleteBillsPartData(transaction, tid, lid) {
             await transaction.delete(this.tableName, { tid: tid, lid: lid });