Browse Source

优化调差新建期功能,把新建期数据分离并优化计算公式时间

ellisran 2 weeks ago
parent
commit
af35c38e8c

+ 1 - 1
app/base/base_bills_service.js

@@ -139,7 +139,7 @@ class BaseBillsSerivce extends TreeService {
             }
             await this.transaction.commit();
         } catch(err) {
-            this.transaction.rollback();
+            await this.transaction.rollback();
             throw err;
         }
 

+ 2 - 2
app/base/base_budget_service.js

@@ -95,7 +95,7 @@ class BaseBudget extends TreeService {
             }
             await this.transaction.commit();
         } catch(err) {
-            this.transaction.rollback();
+            await this.transaction.rollback();
             throw err;
         }
 
@@ -468,4 +468,4 @@ class BaseBudget extends TreeService {
     }
 }
 
-module.exports = BaseBudget;
+module.exports = BaseBudget;

+ 7 - 3
app/controller/material_controller.js

@@ -210,6 +210,12 @@ module.exports = app => {
                     case 'material_col_set':
                         responseData.data = await ctx.service.tender.saveTenderData(ctx.tender.id, { material_col_show: JSON.stringify(data.material_col_data) });
                         break;
+                    case 'make_material_list':
+                        responseData.data = await ctx.service.materialList.makeMaterialList(data);
+                        break;
+                    case 'make_self_list':
+                        responseData.data = await ctx.service.materialList.makeSelfList(data);
+                        break;
                     default: throw '参数有误';
                 }
                 ctx.body = responseData;
@@ -311,6 +317,7 @@ module.exports = app => {
                 qtySourceValueConst: materialConst.qty_source_value,
                 auditType,
             };
+            data.materialStageData = ctx.material.is_stage_self ? await ctx.service.materialStage.getAllDataByCondition({ where: { tid: ctx.tender.id, mid: ctx.material.id } }) : [];
             if ((ctx.material.status === auditConst.status.uncheck || ctx.material.status === auditConst.status.checkNo) && (ctx.session.sessionUser.accountId === ctx.material.user_id || ctx.tender.isTourist) || ctx.session.sessionUser.is_admin) {
                 // data.accountGroup = accountGroup;
                 // 获取所有项目参与者
@@ -474,7 +481,6 @@ module.exports = app => {
                 const stage_list = await ctx.service.stage.getStageMsgByStageId(ctx.material.stage_id);
                 renderData.calcBase = await ctx.service.stage.getMaterialCalcBase(stage_list, ctx.tender.info);
 
-                renderData.materialStageData = ctx.material.is_stage_self ? await ctx.service.materialStage.getAllDataByCondition({ where: { tid: ctx.tender.id, mid: ctx.material.id } }) : [];
                 renderData.materialStageBillsData = ctx.material.is_stage_self ? await ctx.service.materialStageBills.getAllDataByCondition({ where: { tid: ctx.tender.id, mid: ctx.material.id } }) : [];
                 if (ctx.material.is_stage_self) {
                     const calcBaseList = [];
@@ -566,7 +572,6 @@ module.exports = app => {
                     }
                 }
 
-                renderData.materialStageData = ctx.material.is_stage_self ? await ctx.service.materialStage.getAllDataByCondition({ where: { tid: ctx.tender.id, mid: ctx.material.id } }) : [];
                 renderData.materialStageBillsData = ctx.material.is_stage_self ? await ctx.service.materialStageBills.getAllDataByCondition({ where: { tid: ctx.tender.id, mid: ctx.material.id } }) : [];
                 // 取所有已被调用的工料清单表
                 // renderData.materialListData = await ctx.service.materialList.getMaterialData(ctx.tender.id, ctx.material.id);
@@ -1620,7 +1625,6 @@ module.exports = app => {
                     }
                 }
 
-                renderData.materialStageData = ctx.material.is_stage_self ? await ctx.service.materialStage.getAllDataByCondition({ where: { tid: ctx.tender.id, mid: ctx.material.id } }) : [];
                 renderData.materialStageBillsData = ctx.material.is_stage_self ? await ctx.service.materialStageBills.getAllDataByCondition({ where: { tid: ctx.tender.id, mid: ctx.material.id } }) : [];
                 // 取所有已被调用的工料清单表
                 // renderData.materialListData = await ctx.service.materialList.getMaterialData(ctx.tender.id, ctx.material.id);

+ 243 - 232
app/public/js/measure_material.js

@@ -266,239 +266,250 @@ $(function () {
         $('#add-qi').modal('hide');
         $('#okedit').modal('show');
         interval = setInterval(progress, 50);
-        postData(preUrl + '/measure/material/gcl/load', { stage_id, is_stage_self }, function (result) {
-            // console.log(result);
-            const ledger = result.ledger;
-            const pos = result.pos;
-            const gclList = result.gclList;
-            const selfList = result.selfList;
-            // 整理material,针对上期是独立单价并多个不同值的单独设置值进行部分值去除
-            const materialListForSelf = _.uniqWith(_.orderBy(result.materialListForSelf, ['ms_id'], ['desc']), function(item1, item2) {
-                return item1.xmj_id === item2.xmj_id && item1.gcl_id === item2.gcl_id && item1.mx_id === item2.mx_id && item1.mb_id === item2.mb_id;
-            });
-            console.log(materialListForSelf, result.materialListForSelf);
-            const insertGclList = [];
-            const insertList = [];
-            const insertSelfList = [];// 需要单独添加的明细清单工料含量列表
-            const removeGclList = [];
-            const hadQtySelfList = [];
-            if (is_stage_self) {
-                for (const sid of stage_id) {
-                    const curLedger = _.find(result.curLedgerData, {sid: sid});
-                    const curPos = _.find(result.curPosData, {sid: sid});
-                    gclGatherModel.loadLedgerData(_.cloneDeep(ledger), curLedger.ledgerData);
-                    gclGatherModel.loadPosData(_.cloneDeep(pos), curPos.posData);
-                    const gclGatherData = gclGatherModel.gatherGclData();
-                    // console.log(gclGatherData);
-                    const insertGcl = [];
-                    for (const g of gclList) {
-                        const gcl = _.find(gclGatherData, function (item) {
-                            return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: g.gcl_id}) !== -1;
-                        });
-                        if (gcl) {
-                            const ig = _.find(insertGcl, {gcl});
-                            if (ig) {
-                                if (_.findIndex(ig.bills, {mb_id: g.mb_id}) === -1) {
-                                    ig.bills.push(g);
-                                }
-                            } else {
-                                insertGcl.push({
-                                    bills: [g],
-                                    gcl,
-                                    leafXmjs: _.filter(gcl.leafXmjs, function (item) {
-                                        return item.gather_qty !== undefined && item.gather_qty !== null
-                                    }),
-                                })
-                            }
-                        } else {
-                            removeGclList.push(g);
-                        }
-                    }
-                    for (const one of insertGcl) {
-                        if (one.leafXmjs && one.leafXmjs.length > 0) {
-                            for (const xmj of one.leafXmjs) {
-                                const is_self = _.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : '' }) !== -1;// 区分单独计量的明细工料含量
-                                if (is_self) {
-                                    const billsList = _.filter(materialListForSelf, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : '' });
-                                    for (const bill of billsList) {
-                                        if (!_.find(hadQtySelfList, bill)) {
-                                            hadQtySelfList.push(bill);
-                                        }
-                                        insertSelfList.push({
-                                            gcl_id: xmj.gcl_id,
-                                            mx_id: xmj.mx_id ? xmj.mx_id : '',
-                                            xmj_id: xmj.id ? xmj.id : null,
-                                            contract_qty: xmj.contract_qty,
-                                            qc_qty: xmj.qc_qty,
-                                            qc_minus_qty: xmj.qc_minus_qty,
-                                            gather_qty: xmj.gather_qty,
-                                            quantity: bill.quantity,
-                                            expr: bill.expr,
-                                            mb_id: bill.mb_id,
-                                            order: bill.order,
-                                            sid,
-                                        });
-                                    }
-                                } else {
-                                    const newgcl = _.find(gclList, { gcl_id: xmj.gcl_id });
-                                    for (const bill of one.bills) {
-                                        insertList.push({
-                                            gcl_id: xmj.gcl_id,
-                                            mx_id: xmj.mx_id ? xmj.mx_id : '',
-                                            xmj_id: xmj.id ? xmj.id : null,
-                                            contract_qty: xmj.contract_qty,
-                                            qc_qty: xmj.qc_qty,
-                                            qc_minus_qty: xmj.qc_minus_qty,
-                                            gather_qty: xmj.gather_qty,
-                                            quantity: bill.quantity,
-                                            expr: bill.expr,
-                                            mb_id: bill.mb_id,
-                                            order: bill.order,
-                                            sid,
-                                        });
-                                        if (!newgcl) {
-                                            if (_.findIndex(insertGclList, { gcl_id: xmj.gcl_id }) === -1) {
-                                                insertGclList.push({
-                                                    gcl_id: xmj.gcl_id,
-                                                    quantity: bill.quantity,
-                                                    expr: bill.expr,
-                                                    old_quantity: bill.quantity,
-                                                    old_expr: bill.expr,
-                                                    mb_id: bill.mb_id,
-                                                    order: bill.order,
-                                                });
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            } else {
-                const curLedgerData = result.curLedgerData;
-                const curPosData = result.curPosData;
-                gclGatherModel.loadLedgerData(_.cloneDeep(ledger), curLedgerData);
-                gclGatherModel.loadPosData(_.cloneDeep(pos), curPosData);
-                const gclGatherData = gclGatherModel.gatherGclData();
-                const insertGcl = [];
-                for (const g of gclList) {
-                    const gcl = _.find(gclGatherData, function (item) {
-                        return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: g.gcl_id}) !== -1;
-                    });
-                    if (gcl) {
-                        const ig = _.find(insertGcl, {gcl});
-                        if (ig) {
-                            if (_.findIndex(ig.bills, {mb_id: g.mb_id}) === -1) {
-                                ig.bills.push(g);
-                            }
-                        } else {
-                            insertGcl.push({
-                                bills: [g],
-                                gcl,
-                                leafXmjs: _.filter(gcl.leafXmjs, function (item) {
-                                    return item.gather_qty !== undefined && item.gather_qty !== null || (item.qc_minus_qty !== undefined && item.qc_minus_qty !== null)
-                                }),
-                            })
-                        }
-                    } else {
-                        removeGclList.push(g);
-                    }
-                }
-                for (const one of insertGcl) {
-                    if (one.leafXmjs && one.leafXmjs.length > 0) {
-                        for (const xmj of one.leafXmjs) {
-                            const is_self = _.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null }) !== -1;// 区分单独计量的明细工料含量
-                            if (is_self) {
-                                const billsList = _.filter(materialListForSelf, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null });
-                                for (const bill of billsList) {
-                                    hadQtySelfList.push(bill);
-                                    insertSelfList.push({
-                                        gcl_id: xmj.gcl_id,
-                                        mx_id: xmj.mx_id ? xmj.mx_id : '',
-                                        xmj_id: xmj.id ? xmj.id : null,
-                                        contract_qty: xmj.contract_qty,
-                                        qc_qty: xmj.qc_qty,
-                                        qc_minus_qty: xmj.qc_minus_qty,
-                                        gather_qty: xmj.gather_qty,
-                                        quantity: bill.quantity,
-                                        expr: bill.expr,
-                                        mb_id: bill.mb_id,
-                                        order: bill.order,
-                                    });
-                                }
-                            } else {
-                                const newgcl = _.find(gclList, { gcl_id: xmj.gcl_id });
-                                for (const bill of one.bills) {
-                                    insertList.push({
-                                        gcl_id: xmj.gcl_id,
-                                        mx_id: xmj.mx_id ? xmj.mx_id : '',
-                                        xmj_id: xmj.id ? xmj.id : null,
-                                        contract_qty: xmj.contract_qty,
-                                        qc_qty: xmj.qc_qty,
-                                        qc_minus_qty: xmj.qc_minus_qty,
-                                        gather_qty: xmj.gather_qty,
-                                        quantity: bill.quantity,
-                                        expr: bill.expr,
-                                        mb_id: bill.mb_id,
-                                        order: bill.order,
-                                    });
-                                    if (!newgcl) {
-                                        insertGclList.push({
-                                            gcl_id: xmj.gcl_id,
-                                            quantity: bill.quantity,
-                                            expr: bill.expr,
-                                            old_quantity: bill.quantity,
-                                            old_expr: bill.expr,
-                                            mb_id: bill.mb_id,
-                                            order: bill.order,
-                                        });
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            // 通过比较materialListForSelf和hadQtySelfList不重合部分,得出本期为null的gather_qty列表,插入到insertSelfList中
-            const pushSelfList = _.xorWith(materialListForSelf, hadQtySelfList, _.isEqual);
-            if (pushSelfList.length > 0) {
-                for (const ps of pushSelfList) {
-                    insertSelfList.push({
-                        gcl_id: ps.gcl_id,
-                        mx_id: ps.mx_id,
-                        xmj_id: ps.xmj_id,
-                        contract_qty: null,
-                        qc_qty: null,
-                        qc_minus_qty: null,
-                        gather_qty: null,
-                        quantity: ps.quantity,
-                        expr: ps.expr,
-                        mb_id: ps.mb_id,
-                        order: ps.order,
-                    });
-                }
-            }
-            // 可能需要新增list_gcl表
-            newMaterialData.material_list = insertList;
-            newMaterialData.material_self_list = insertSelfList;
-            newMaterialData.insertGclList = insertGclList;
-            newMaterialData.removeGclList = removeGclList;
-            console.log(newMaterialData);
-            console.log(insertSelfList);
-            postData(preUrl + '/measure/material/add', newMaterialData, function (result) {
-                window.location.href = preUrl + '/measure/material/' + result.order;
-            }, function () {
-                stop = true;
-                clearInterval(interval);
-                console.log(_self.parents('div[id="add-qi"]'));
-                $('#add-qi').modal('show');
-                $('#okedit').modal('hide');
-                _self.parents('div[id="add-qi"]').modal('show');
-                _self.attr('disabled', false).text('确认添加');
-            });
-            return;
+        postData(preUrl + '/measure/material/add', newMaterialData, function (result) {
+            window.location.href = preUrl + '/measure/material/' + result.order;
+        }, function () {
+            stop = true;
+            clearInterval(interval);
+            console.log(_self.parents('div[id="add-qi"]'));
+            $('#add-qi').modal('show');
+            $('#okedit').modal('hide');
+            _self.parents('div[id="add-qi"]').modal('show');
+            _self.attr('disabled', false).text('确认添加');
         });
+        // postData(preUrl + '/measure/material/gcl/load', { stage_id, is_stage_self }, function (result) {
+        //     // console.log(result);
+        //     const ledger = result.ledger;
+        //     const pos = result.pos;
+        //     const gclList = result.gclList;
+        //     const selfList = result.selfList;
+        //     // 整理material,针对上期是独立单价并多个不同值的单独设置值进行部分值去除
+        //     const materialListForSelf = _.uniqWith(_.orderBy(result.materialListForSelf, ['ms_id'], ['desc']), function(item1, item2) {
+        //         return item1.xmj_id === item2.xmj_id && item1.gcl_id === item2.gcl_id && item1.mx_id === item2.mx_id && item1.mb_id === item2.mb_id;
+        //     });
+        //     console.log(materialListForSelf, result.materialListForSelf);
+        //     const insertGclList = [];
+        //     const insertList = [];
+        //     const insertSelfList = [];// 需要单独添加的明细清单工料含量列表
+        //     const removeGclList = [];
+        //     const hadQtySelfList = [];
+        //     if (is_stage_self) {
+        //         for (const sid of stage_id) {
+        //             const curLedger = _.find(result.curLedgerData, {sid: sid});
+        //             const curPos = _.find(result.curPosData, {sid: sid});
+        //             gclGatherModel.loadLedgerData(_.cloneDeep(ledger), curLedger.ledgerData);
+        //             gclGatherModel.loadPosData(_.cloneDeep(pos), curPos.posData);
+        //             const gclGatherData = gclGatherModel.gatherGclData();
+        //             // console.log(gclGatherData);
+        //             const insertGcl = [];
+        //             for (const g of gclList) {
+        //                 const gcl = _.find(gclGatherData, function (item) {
+        //                     return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: g.gcl_id}) !== -1;
+        //                 });
+        //                 if (gcl) {
+        //                     const ig = _.find(insertGcl, {gcl});
+        //                     if (ig) {
+        //                         if (_.findIndex(ig.bills, {mb_id: g.mb_id}) === -1) {
+        //                             ig.bills.push(g);
+        //                         }
+        //                     } else {
+        //                         insertGcl.push({
+        //                             bills: [g],
+        //                             gcl,
+        //                             leafXmjs: _.filter(gcl.leafXmjs, function (item) {
+        //                                 return item.gather_qty !== undefined && item.gather_qty !== null
+        //                             }),
+        //                         })
+        //                     }
+        //                 } else {
+        //                     removeGclList.push(g);
+        //                 }
+        //             }
+        //             for (const one of insertGcl) {
+        //                 if (one.leafXmjs && one.leafXmjs.length > 0) {
+        //                     for (const xmj of one.leafXmjs) {
+        //                         const is_self = _.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : '' }) !== -1;// 区分单独计量的明细工料含量
+        //                         if (is_self) {
+        //                             const billsList = _.filter(materialListForSelf, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : '' });
+        //                             for (const bill of billsList) {
+        //                                 if (!_.find(hadQtySelfList, bill)) {
+        //                                     hadQtySelfList.push(bill);
+        //                                 }
+        //                                 insertSelfList.push({
+        //                                     gcl_id: xmj.gcl_id,
+        //                                     mx_id: xmj.mx_id ? xmj.mx_id : '',
+        //                                     xmj_id: xmj.id ? xmj.id : null,
+        //                                     contract_qty: xmj.contract_qty,
+        //                                     qc_qty: xmj.qc_qty,
+        //                                     qc_minus_qty: xmj.qc_minus_qty,
+        //                                     gather_qty: xmj.gather_qty,
+        //                                     quantity: bill.quantity,
+        //                                     expr: bill.expr,
+        //                                     mb_id: bill.mb_id,
+        //                                     order: bill.order,
+        //                                     sid,
+        //                                 });
+        //                             }
+        //                         } else {
+        //                             const newgcl = _.find(gclList, { gcl_id: xmj.gcl_id });
+        //                             for (const bill of one.bills) {
+        //                                 insertList.push({
+        //                                     gcl_id: xmj.gcl_id,
+        //                                     mx_id: xmj.mx_id ? xmj.mx_id : '',
+        //                                     xmj_id: xmj.id ? xmj.id : null,
+        //                                     contract_qty: xmj.contract_qty,
+        //                                     qc_qty: xmj.qc_qty,
+        //                                     qc_minus_qty: xmj.qc_minus_qty,
+        //                                     gather_qty: xmj.gather_qty,
+        //                                     quantity: bill.quantity,
+        //                                     expr: bill.expr,
+        //                                     mb_id: bill.mb_id,
+        //                                     order: bill.order,
+        //                                     sid,
+        //                                 });
+        //                                 if (!newgcl) {
+        //                                     if (_.findIndex(insertGclList, { gcl_id: xmj.gcl_id }) === -1) {
+        //                                         insertGclList.push({
+        //                                             gcl_id: xmj.gcl_id,
+        //                                             quantity: bill.quantity,
+        //                                             expr: bill.expr,
+        //                                             old_quantity: bill.quantity,
+        //                                             old_expr: bill.expr,
+        //                                             mb_id: bill.mb_id,
+        //                                             order: bill.order,
+        //                                         });
+        //                                     }
+        //                                 }
+        //                             }
+        //                         }
+        //                     }
+        //                 }
+        //             }
+        //         }
+        //     } else {
+        //         const curLedgerData = result.curLedgerData;
+        //         const curPosData = result.curPosData;
+        //         gclGatherModel.loadLedgerData(_.cloneDeep(ledger), curLedgerData);
+        //         gclGatherModel.loadPosData(_.cloneDeep(pos), curPosData);
+        //         const gclGatherData = gclGatherModel.gatherGclData();
+        //         const insertGcl = [];
+        //         for (const g of gclList) {
+        //             const gcl = _.find(gclGatherData, function (item) {
+        //                 return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: g.gcl_id}) !== -1;
+        //             });
+        //             if (gcl) {
+        //                 const ig = _.find(insertGcl, {gcl});
+        //                 if (ig) {
+        //                     if (_.findIndex(ig.bills, {mb_id: g.mb_id}) === -1) {
+        //                         ig.bills.push(g);
+        //                     }
+        //                 } else {
+        //                     insertGcl.push({
+        //                         bills: [g],
+        //                         gcl,
+        //                         leafXmjs: _.filter(gcl.leafXmjs, function (item) {
+        //                             return item.gather_qty !== undefined && item.gather_qty !== null || (item.qc_minus_qty !== undefined && item.qc_minus_qty !== null)
+        //                         }),
+        //                     })
+        //                 }
+        //             } else {
+        //                 removeGclList.push(g);
+        //             }
+        //         }
+        //         for (const one of insertGcl) {
+        //             if (one.leafXmjs && one.leafXmjs.length > 0) {
+        //                 for (const xmj of one.leafXmjs) {
+        //                     const is_self = _.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null }) !== -1;// 区分单独计量的明细工料含量
+        //                     if (is_self) {
+        //                         const billsList = _.filter(materialListForSelf, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null });
+        //                         for (const bill of billsList) {
+        //                             hadQtySelfList.push(bill);
+        //                             insertSelfList.push({
+        //                                 gcl_id: xmj.gcl_id,
+        //                                 mx_id: xmj.mx_id ? xmj.mx_id : '',
+        //                                 xmj_id: xmj.id ? xmj.id : null,
+        //                                 contract_qty: xmj.contract_qty,
+        //                                 qc_qty: xmj.qc_qty,
+        //                                 qc_minus_qty: xmj.qc_minus_qty,
+        //                                 gather_qty: xmj.gather_qty,
+        //                                 quantity: bill.quantity,
+        //                                 expr: bill.expr,
+        //                                 mb_id: bill.mb_id,
+        //                                 order: bill.order,
+        //                             });
+        //                         }
+        //                     } else {
+        //                         const newgcl = _.find(gclList, { gcl_id: xmj.gcl_id });
+        //                         for (const bill of one.bills) {
+        //                             insertList.push({
+        //                                 gcl_id: xmj.gcl_id,
+        //                                 mx_id: xmj.mx_id ? xmj.mx_id : '',
+        //                                 xmj_id: xmj.id ? xmj.id : null,
+        //                                 contract_qty: xmj.contract_qty,
+        //                                 qc_qty: xmj.qc_qty,
+        //                                 qc_minus_qty: xmj.qc_minus_qty,
+        //                                 gather_qty: xmj.gather_qty,
+        //                                 quantity: bill.quantity,
+        //                                 expr: bill.expr,
+        //                                 mb_id: bill.mb_id,
+        //                                 order: bill.order,
+        //                             });
+        //                             if (!newgcl) {
+        //                                 insertGclList.push({
+        //                                     gcl_id: xmj.gcl_id,
+        //                                     quantity: bill.quantity,
+        //                                     expr: bill.expr,
+        //                                     old_quantity: bill.quantity,
+        //                                     old_expr: bill.expr,
+        //                                     mb_id: bill.mb_id,
+        //                                     order: bill.order,
+        //                                 });
+        //                             }
+        //                         }
+        //                     }
+        //                 }
+        //             }
+        //         }
+        //     }
+        //     // 通过比较materialListForSelf和hadQtySelfList不重合部分,得出本期为null的gather_qty列表,插入到insertSelfList中
+        //     const pushSelfList = _.xorWith(materialListForSelf, hadQtySelfList, _.isEqual);
+        //     if (pushSelfList.length > 0) {
+        //         for (const ps of pushSelfList) {
+        //             insertSelfList.push({
+        //                 gcl_id: ps.gcl_id,
+        //                 mx_id: ps.mx_id,
+        //                 xmj_id: ps.xmj_id,
+        //                 contract_qty: null,
+        //                 qc_qty: null,
+        //                 qc_minus_qty: null,
+        //                 gather_qty: null,
+        //                 quantity: ps.quantity,
+        //                 expr: ps.expr,
+        //                 mb_id: ps.mb_id,
+        //                 order: ps.order,
+        //             });
+        //         }
+        //     }
+        //     // 可能需要新增list_gcl表
+        //     newMaterialData.material_list = insertList;
+        //     newMaterialData.material_self_list = insertSelfList;
+        //     newMaterialData.insertGclList = insertGclList;
+        //     newMaterialData.removeGclList = removeGclList;
+        //     console.log(newMaterialData);
+        //     console.log(insertSelfList);
+        //     postData(preUrl + '/measure/material/add', newMaterialData, function (result) {
+        //         window.location.href = preUrl + '/measure/material/' + result.order;
+        //     }, function () {
+        //         stop = true;
+        //         clearInterval(interval);
+        //         console.log(_self.parents('div[id="add-qi"]'));
+        //         $('#add-qi').modal('show');
+        //         $('#okedit').modal('hide');
+        //         _self.parents('div[id="add-qi"]').modal('show');
+        //         _self.attr('disabled', false).text('确认添加');
+        //     });
+        //     return;
+        // });
         // $(this).parents('form').submit();
     });
 

+ 1 - 1
app/service/category.js

@@ -189,7 +189,7 @@ module.exports = app => {
                 for (const d of data) {
                     this.transaction.update(this.tableName, {id: d.id, level: d.level});
                 }
-                this.transaction.commit();
+                await this.transaction.commit();
             } catch (err) {
                 await this.transaction.rollback();
                 throw err;

+ 1 - 1
app/service/change.js

@@ -256,7 +256,7 @@ module.exports = app => {
                 await this.transaction.insert(this.ctx.service.changeAudit.tableName, changeaudit);
 
                 result = change;
-                this.transaction.commit();
+                await this.transaction.commit();
             } catch (error) {
                 console.log(error);
                 // 回滚

+ 1 - 1
app/service/change_apply.js

@@ -131,7 +131,7 @@ module.exports = app => {
                     }
                 }
                 result = change;
-                this.transaction.commit();
+                await this.transaction.commit();
             } catch (error) {
                 console.log(error);
                 // 回滚

+ 1 - 1
app/service/change_company.js

@@ -67,7 +67,7 @@ module.exports = app => {
                         }
                     }
                 }
-                this.transaction.commit();
+                await this.transaction.commit();
             } catch (error) {
                 console.log(error);
                 // 回滚

+ 1 - 1
app/service/change_plan.js

@@ -152,7 +152,7 @@ module.exports = app => {
                     }
                 }
                 result = change;
-                this.transaction.commit();
+                await this.transaction.commit();
             } catch (error) {
                 console.log(error);
                 // 回滚

+ 1 - 1
app/service/change_project.js

@@ -121,7 +121,7 @@ module.exports = app => {
                     }
                 }
                 result = change;
-                this.transaction.commit();
+                await this.transaction.commit();
             } catch (error) {
                 console.log(error);
                 // 回滚

+ 2 - 2
app/service/construction_unit.js

@@ -100,11 +100,11 @@ module.exports = app => {
                     //     }
                     // );
                 }
-                transaction.commit();
+                await transaction.commit();
                 const result = operate.affectedRows > 0;
                 return result;
             } catch (e) {
-                transaction.rollback();
+                await transaction.rollback();
             }
         }
 

+ 2 - 2
app/service/datacollect_tender.js

@@ -83,10 +83,10 @@ module.exports = app => {
                         await transaction.delete(this.tableName, { pid, tid: d });
                     }
                 }
-                transaction.commit();
+                await transaction.commit();
             } catch (e) {
                 console.log(e);
-                transaction.rollback();
+                await transaction.rollback();
             }
         }
 

+ 29 - 25
app/service/material.js

@@ -205,6 +205,8 @@ module.exports = app => {
                 qty_source: data.qty_source,
                 is_new_qty: 1,
                 rate: 9,
+                calc_stage: data.stage_id.join(','),
+                calc_tp: 1,
             };
             const transaction = await this.db.beginTransaction();
             try {
@@ -214,6 +216,8 @@ module.exports = app => {
                     newMaterial.pre_tp = this.ctx.helper.add(preMaterial.m_tp, preMaterial.pre_tp);
                     newMaterial.ex_pre_tp = this.ctx.helper.add(preMaterial.ex_tp, preMaterial.ex_pre_tp);
                     newMaterial.m_tax_pre_tp = preMaterial.material_tax ? this.ctx.helper.add(preMaterial.m_tax_tp, preMaterial.m_tax_pre_tp) : preMaterial.m_tax_pre_tp;
+                    newMaterial.calc_stage = '';
+                    newMaterial.calc_tp = 0;
                 }
                 // 新增期记录
                 const result = await transaction.insert(this.tableName, newMaterial);
@@ -253,38 +257,38 @@ module.exports = app => {
                     // 复制单独计量调差清单
                     const preSelfList = await this.ctx.service.materialListSelf.getAllDataByCondition({ where: { tid: this.ctx.tender.id, mid: preMaterial.id } });
                     await this.ctx.service.materialListSelf.copyNewStageSelfList(transaction, preSelfList, newMaterial.id);
-                    // 复制调差清单工料关联表
-                    // await this.ctx.service.materialList.copyPreMaterialList(transaction, preMaterial, newMaterial);
-                    await this.ctx.service.materialList.copyPreMaterialList2(transaction, data.material_list, data.material_self_list, preNotJoinList, newMaterial, insertMaterialStage);
-                    // 新增或删除list_gcl表
-                    await this.ctx.service.materialListGcl.insertOrDelGcl(transaction, data.insertGclList, data.removeGclList, newMaterial.id);
-                    // 设置list_gcl表old=>new更新
-                    await this.ctx.service.materialListGcl.setNewOldData(transaction, this.ctx.tender.id);
-                    // 修改本期应耗数量值和有效价差,需要剔除不参与调差的清单数据,并返回总金额
-                    let m_tp = null;
-                    let m_tax_tp = null;
-                    let rate_tp = null;
-                    if (data.is_stage_self) {
-                        [m_tp, m_tax_tp, rate_tp] = await this.ctx.service.materialStageBills.insertBills(transaction, this.ctx.tender.id, newMaterial.id, newMaterial.stage_id, insertMaterialStage, JSON.parse(newMaterial.decimal), preMaterial.is_stage_self, data.qty_source, newMaterial.rate);
-                    } else {
-                        [m_tp, m_tax_tp, rate_tp] = await this.ctx.service.materialBills.updateNewMaterial(transaction, this.ctx.tender.id, newMaterial.id, this.ctx, newMaterial.stage_id, JSON.parse(newMaterial.decimal), preMaterial.is_stage_self, data.qty_source, newMaterial.rate);
-                    }
+                //     // 复制调差清单工料关联表
+                //     // await this.ctx.service.materialList.copyPreMaterialList(transaction, preMaterial, newMaterial);
+                //     await this.ctx.service.materialList.copyPreMaterialList2(transaction, data.material_list, data.material_self_list, preNotJoinList, newMaterial, insertMaterialStage);
+                //     // 新增或删除list_gcl表
+                //     await this.ctx.service.materialListGcl.insertOrDelGcl(transaction, data.insertGclList, data.removeGclList, newMaterial.id);
+                //     // 设置list_gcl表old=>new更新
+                //     await this.ctx.service.materialListGcl.setNewOldData(transaction, this.ctx.tender.id);
+                //     // 修改本期应耗数量值和有效价差,需要剔除不参与调差的清单数据,并返回总金额
+                //     let m_tp = null;
+                //     let m_tax_tp = null;
+                //     let rate_tp = null;
+                //     if (data.is_stage_self) {
+                //         [m_tp, m_tax_tp, rate_tp] = await this.ctx.service.materialStageBills.insertBills(transaction, this.ctx.tender.id, newMaterial.id, newMaterial.stage_id, insertMaterialStage, JSON.parse(newMaterial.decimal), preMaterial.is_stage_self, data.qty_source, newMaterial.rate);
+                //     } else {
+                //         [m_tp, m_tax_tp, rate_tp] = await this.ctx.service.materialBills.updateNewMaterial(transaction, this.ctx.tender.id, newMaterial.id, this.ctx, newMaterial.stage_id, JSON.parse(newMaterial.decimal), preMaterial.is_stage_self, data.qty_source, newMaterial.rate);
+                //     }
                     // 修改现行价格指数,并返回调差基数json
                     const ex_calc = await this.ctx.service.materialExponent.updateNewMaterial(transaction, newMaterial.id, this.ctx, newMaterial.stage_id, preMaterial.ex_calc, JSON.parse(newMaterial.decimal));
-                    // 计算得出本期总金额
-                    // 找出当前人并更新tp_data
-                    const tp_data = await this.ctx.service.materialAudit.getTpData(transaction, newMaterial.id, JSON.parse(newMaterial.decimal));
+                //     // 计算得出本期总金额
+                //     // 找出当前人并更新tp_data
+                //     const tp_data = await this.ctx.service.materialAudit.getTpData(transaction, newMaterial.id, JSON.parse(newMaterial.decimal));
                     const updateMaterialData = {
                         id: newMaterial.id,
-                        m_tp,
-                        m_tax_tp,
-                        rate_tp,
+                        // m_tp,
+                        // m_tax_tp,
+                        // rate_tp,
                         ex_calc: JSON.stringify(ex_calc),
-                        tp_data: JSON.stringify(tp_data),
+                        // tp_data: JSON.stringify(tp_data),
                     };
                     await transaction.update(this.tableName, updateMaterialData);
-                    // 删除material_list表冗余数据,减少表数据量
-                    await transaction.delete(this.ctx.service.materialList.tableName, { tid: this.ctx.tender.id, gather_qty: null, is_self: 0 });
+                //     // 删除material_list表冗余数据,减少表数据量
+                //     await transaction.delete(this.ctx.service.materialList.tableName, { tid: this.ctx.tender.id, gather_qty: null, is_self: 0 });
                 }
 
                 await transaction.commit();

+ 134 - 6
app/service/material_list.js

@@ -867,15 +867,143 @@ module.exports = app => {
 
         async getMbQuantity(transaction, mid, qty_source, qty_decimal, mb_id, ms_id = null, needRound = 1) {
             const msSql = ms_id ? ' AND `ms_id` = ' + ms_id : '';
-            const sql = 'SELECT SUM(' + this.ctx.helper.getQtySource(qty_source) + '*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=?' + msSql + ' AND `is_join`=1';
+            const sql = `
+                SELECT
+                    SUM(CASE WHEN is_join = 1 THEN ${this.ctx.helper.getQtySource(qty_source)} * quantity ELSE 0 END) AS quantity1,
+                    SUM(CASE WHEN is_join = 2 THEN ${this.ctx.helper.getQtySource(qty_source, 1)} * quantity ELSE 0 END) AS quantity2
+                  FROM ${this.tableName}
+                  WHERE mid = ? AND mb_id = ?${msSql}
+                `;
             const sqlParam = [mid, mb_id];
-            const mb_quantity = await transaction.queryOne(sql, sqlParam);
-            const sql2 = 'SELECT SUM(' + this.ctx.helper.getQtySource(qty_source, 1) + '*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=?' + msSql + ' AND `is_join`=2';
-            const sqlParam2 = [mid, mb_id];
-            const mb_quantity2 = await transaction.queryOne(sql2, sqlParam2);
-            const newQuantity = this.ctx.helper.add(mb_quantity.quantity, mb_quantity2.quantity);
+            const result = await transaction.queryOne(sql, sqlParam);
+            const newQuantity = this.ctx.helper.add(result.quantity1, result.quantity2);
             return needRound ? this.ctx.helper.round(newQuantity, qty_decimal) : newQuantity;
         }
+
+        async makeMaterialList(data) {
+            if (!data.mid) {
+                throw '参数错误';
+            }
+            const transaction = await this.db.beginTransaction();
+            try {
+                const material = await this.ctx.service.material.getDataById(data.mid);
+                const newCalcStage = material.is_stage_self ? (material.calc_stage ? material.calc_stage.split(',') : []) : data.stage_id;
+                if (material.is_stage_self) newCalcStage.push(data.stage_id);
+                const materialStages = material.is_stage_self ? await this.ctx.service.materialStage.getAllDataByCondition({ where: { mid: material.id } }) : [];
+                const notJoinList = await this.ctx.service.materialListNotjoin.getAllDataByCondition({ where: { tid: this.ctx.tender.id, mid: material.id } });
+                // 复制调差清单工料关联表
+                // await this.ctx.service.materialList.copyPreMaterialList(transaction, preMaterial, newMaterial);
+                await this.copyPreMaterialList2(transaction, data.material_list, [], notJoinList, material, materialStages);
+                // 新增或删除list_gcl表
+                await this.ctx.service.materialListGcl.insertOrDelGcl(transaction, data.insertGclList, data.removeGclList, material.id);
+                // 修改本期应耗数量值和有效价差,需要剔除不参与调差的清单数据,并返回总金额
+                const materials = await this.getAllDataByCondition({
+                    where: { tid: this.ctx.tender.id },
+                    order: ['order'],
+                });
+                const preMaterial = materials[materials.length - 1];
+                if (material.is_stage_self) {
+                    await this.ctx.service.materialStageBills.insertMsBills(transaction, this.ctx.tender.id, material.id, this._.find(materialStages, { sid: parseInt(data.stage_id) }), JSON.parse(material.decimal), preMaterial.is_stage_self, material.qty_source, material.rate);
+                    await transaction.update(this.ctx.service.material.tableName, {
+                        id: material.id, calc_stage: newCalcStage.join(','),
+                    });
+                } else {
+                    let m_tp = null;
+                    let m_tax_tp = null;
+                    let rate_tp = null;
+                    [m_tp, m_tax_tp, rate_tp] = await this.ctx.service.materialBills.updateNewMaterial(transaction, this.ctx.tender.id, material.id, this.ctx, material.stage_id, JSON.parse(material.decimal), preMaterial.is_stage_self, material.qty_source, material.rate);
+                    const updateMaterialData = {
+                        id: material.id,
+                        m_tp,
+                        m_tax_tp,
+                        rate_tp,
+                        calc_tp: 1,
+                        calc_stage: newCalcStage,
+                    };
+                    await transaction.update(this.ctx.service.material.tableName, updateMaterialData);
+                }
+                await transaction.commit();
+                return true;
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+        }
+
+        async makeSelfList(data) {
+            if (!data.mid) {
+                throw '参数错误';
+            }
+            const transaction = await this.db.beginTransaction();
+            try {
+                const material = await this.ctx.service.material.getDataById(data.mid);
+                const materialStages = material.is_stage_self ? await this.ctx.service.materialStage.getAllDataByCondition({ where: { mid: material.id } }) : [];
+                const notJoinList = await this.ctx.service.materialListNotjoin.getAllDataByCondition({ where: { tid: this.ctx.tender.id, mid: material.id } });
+                // 复制调差清单工料关联表
+                // await this.ctx.service.materialList.copyPreMaterialList(transaction, preMaterial, newMaterial);
+                await this.copyPreMaterialList2(transaction, [], data.material_self_list, notJoinList, material, materialStages);
+                // 设置list_gcl表old=>new更新
+                await this.ctx.service.materialListGcl.setNewOldData(transaction, this.ctx.tender.id);
+                // 修改本期应耗数量值和有效价差,需要剔除不参与调差的清单数据,并返回总金额
+                // 找出当前人并更新tp_data
+                const tp_data = await this.ctx.service.materialAudit.getTpData(transaction, material.id, JSON.parse(material.decimal));
+                const updateMaterialData = {
+                    id: material.id,
+                    calc_tp: 1,
+                    tp_data: JSON.stringify(tp_data),
+                };
+                if (material.is_stage_self) {
+                    // 更新bill表和截止上期数据
+                    const materialDecimal = JSON.parse(material.decimal);
+                    const updateBillsData = [];
+                    const billsList = await transaction.select(this.ctx.service.materialBills.tableName, { where: { tid: this.ctx.tender.id } });
+                    const stageBillsDatas = await this.ctx.service.materialStageBills.getAllDataByCondition({ where: { tid: this.ctx.tender.id, mid: material.id } });
+                    for (const mb of billsList) {
+                        const [newmsg_spread, newm_spread] = await this.ctx.service.materialStageBills.getSpread(mb, null, materialDecimal.up);
+                        const newTp = this._.sumBy(stageBillsDatas, function(item) {
+                            return item.mb_id === mb.id ? item.m_tp : 0;
+                        });
+                        const oneBillsData = {
+                            id: mb.id,
+                            quantity: null,
+                            expr: null,
+                            msg_tp: null,
+                            msg_times: null,
+                            msg_spread: newmsg_spread,
+                            m_spread: newm_spread,
+                            origin: null,
+                            m_tp: newTp,
+                            pre_tp: mb.m_tp !== null ? this.ctx.helper.add(mb.pre_tp, mb.m_tp) : mb.pre_tp,
+                            m_tax_tp: this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mb.m_tax, 100))), materialDecimal.tp),
+                            tax_pre_tp: mb.m_tax_tp !== null ? this.ctx.helper.add(mb.tax_pre_tp, mb.m_tax_tp) : mb.tax_pre_tp,
+                        };
+                        updateBillsData.push(oneBillsData);
+                    }
+                    await transaction.updateRows(this.ctx.service.materialBills.tableName, updateBillsData);
+                    // 计算得出本期总金额
+                    let m_tp = 0;
+                    let m_tax_tp = 0;
+                    let rate_tp = 0;
+                    for (const s of materialStages) {
+                        m_tp = this.ctx.helper.add(m_tp, s.m_tp);
+                        m_tax_tp = this.ctx.helper.add(m_tax_tp, s.m_tax_tp);
+                        const sRateTp = this.ctx.helper.round(this.ctx.helper.mul(s.m_tp, (1 + this.ctx.helper.div(material.rate, 100))), materialDecimal.tp);
+                        rate_tp = this.ctx.helper.add(rate_tp, sRateTp);
+                    }
+                    updateMaterialData.m_tp = m_tp;
+                    updateMaterialData.m_tax_tp = m_tax_tp;
+                    updateMaterialData.rate_tp = rate_tp;
+                }
+                await transaction.update(this.ctx.service.material.tableName, updateMaterialData);
+                // 删除material_list表冗余数据,减少表数据量
+                await transaction.delete(this.tableName, { tid: this.ctx.tender.id, gather_qty: null, is_self: 0 });
+                await transaction.commit();
+                return true;
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+        }
     }
     return MaterialList;
 };

+ 36 - 0
app/service/material_stage_bills.js

@@ -43,7 +43,9 @@ module.exports = app => {
                             ms_id: ms.id,
                             is_summary: b.is_summary,
                         };
+                        console.time('calc');
                         const [one_tp, one_tax_tp] = await this.calcQuantityByMB(transaction, mid, b, oneStageBillsData, materialCalculator, decimal, pre_is_stage_self, qty_source);
+                        console.timeEnd('calc');
                         insertStageBillsData.push(oneStageBillsData);
                         m_tp = this.ctx.helper.add(m_tp, one_tp);
                         m_tax_tp = this.ctx.helper.add(m_tax_tp, one_tax_tp);
@@ -96,6 +98,40 @@ module.exports = app => {
             return [m_tp, m_tax_tp, rate_tp];
         }
 
+        async insertMsBills(transaction, tid, mid, ms, decimal, pre_is_stage_self = 0, qty_source = 1, rate) {
+            // 复制工料表并生成
+            const billsList = await transaction.select(this.ctx.service.materialBills.tableName, { where: { tid } });
+            if (billsList.length > 0) {
+                const insertStageBillsData = [];
+                const materialCalculator = new MaterialCalculator(this.ctx, ms.sid, this.ctx.tender.info);
+                for (const b of billsList) {
+                    const oneStageBillsData = {
+                        tid,
+                        mid,
+                        mb_id: b.id,
+                        ms_id: ms.id,
+                        is_summary: b.is_summary,
+                    };
+                    await this.calcQuantityByMB(transaction, mid, b, oneStageBillsData, materialCalculator, decimal, pre_is_stage_self, qty_source);
+                    insertStageBillsData.push(oneStageBillsData);
+                }
+                await transaction.insert(this.tableName, insertStageBillsData);
+                // 更新单个期的本期金额
+                const newTp = this._.sumBy(insertStageBillsData, function(item) {
+                    return item.ms_id === ms.id ? item.m_tp : 0;
+                });
+                const newTaxTp = this._.sumBy(insertStageBillsData, function(item) {
+                    return item.ms_id === ms.id ? item.m_tax_tp : 0;
+                });
+                const oneStageData = {
+                    id: ms.id,
+                    m_tp: newTp,
+                    m_tax_tp: newTaxTp,
+                };
+                await transaction.update(this.ctx.service.materialStage.tableName, oneStageData);
+            }
+        }
+
         // 添加工料时同步生成
         async add(transaction, id, remark = null) {
             for (const sid of this.ctx.material.stage_id.split(',')) {

+ 1 - 1
app/service/project_account.js

@@ -693,7 +693,7 @@ module.exports = app => {
                     this.syncAccount(projectData.code, accountData.account, account);
                 }
 
-                this.transaction.commit();
+                await this.transaction.commit();
             } catch (error) {
                 this.transaction.rollback();
             }

+ 6 - 3
app/service/role_rpt_rel.js

@@ -128,7 +128,10 @@ module.exports = app => {
             } catch (ex) {
                 console.log(ex);
                 // 回滚
-                await this.transaction.rollback();
+                if (this.transaction) {
+                    await this.transaction.rollback();
+                    this.transaction = null;
+                }
             }
             return rst;
         }
@@ -236,7 +239,7 @@ module.exports = app => {
                 this.transaction = await this.db.beginTransaction();
                 try {
                     await this.transaction.delete(this.tableName, data);
-                    this.transaction.commit();
+                    await this.transaction.commit();
                     await this.createRoleRelationship(tenderId, rptId, sid, businessId, srcKey, newRelArr);
                 } catch (ex) {
                     console.log(ex.toString());
@@ -272,7 +275,7 @@ module.exports = app => {
                 this.transaction = await this.db.beginTransaction();
                 try {
                     await this.transaction.delete(this.tableName, data);
-                    this.transaction.commit();
+                    await this.transaction.commit();
                     await this.createRoleRelationship(param[0], param[2], param[1], bzId, srcKey, newRelArr);
                 } catch (ex) {
                     console.log(ex.toString());

+ 1 - 1
app/service/rpt_tpl.js

@@ -92,7 +92,7 @@ module.exports = app => {
             try {
                 const data = { id: tplId, rpt_type: 0, rpt_tpl_name: tplName, rpt_content: JSON.stringify(tplObj) };
                 rst = await this.transaction.update(this.tableName, data);
-                this.transaction.commit();
+                await this.transaction.commit();
             } catch (ex) {
                 console.log(ex);
                 // 回滚

+ 2 - 2
app/service/rpt_tree_node.js

@@ -139,11 +139,11 @@ module.exports = app => {
                 // const operate = await this.db.update(this.tableName, topNode);
                 // console.log(operate.affectedRows);
                 // return operate.affectedRows === 1;
-                this.transaction.commit();
+                await this.transaction.commit();
                 return true;
             } catch (ex) {
                 console.log(ex);
-                this.transaction.rollback();
+                await this.transaction.rollback();
                 return false;
             }
         }

+ 4 - 4
app/service/rpt_tree_node_cust.js

@@ -120,13 +120,13 @@ module.exports = app => {
                     custNode[0].rpt_tpl_items = newNodeItems;
                     custNode[0].cust_acc_id = -1;
                     rst = await this.transaction.update(this.tableName, custNode[0]);
-                    this.transaction.commit();
+                    await this.transaction.commit();
                 } else {
                     rst = await this.createCustNodeByTenderId(cust_acc_id, tender_id, newNodeItems);
                 }
             } catch (ex) {
                 console.log(ex);
-                this.transaction.rollback();
+                await this.transaction.rollback();
                 rst = null;
             } finally {
                 return rst;
@@ -145,7 +145,7 @@ module.exports = app => {
                     // custNode[0].rpt_tpl_items = newNodeItems;
                     custNode[0].rpt_tpl_items = JSON.stringify(orgNodeItems);
                     rst = await this.transaction.update(this.tableName, custNode[0]);
-                    this.transaction.commit();
+                    await this.transaction.commit();
                 } else {
                     const nodeItems = {};
                     nodeItems[custSelectKeys[0]] = newNodeItems.common;
@@ -155,7 +155,7 @@ module.exports = app => {
                 }
             } catch (ex) {
                 console.log(ex);
-                this.transaction.rollback();
+                await this.transaction.rollback();
                 rst = null;
             } finally {
                 return rst;

+ 378 - 2
app/view/material/audit_modal.ejs

@@ -963,10 +963,13 @@
         const accountList = JSON.parse(unescape('<%- escape(JSON.stringify(accountList)) %>'));
         const material_uid = parseInt('<%= ctx.material.user_id %>');
         const auditorList = JSON.parse(unescape('<%- escape(JSON.stringify(ctx.material.auditors2)) %>'));
-        const cur_tenderid = parseInt('<%- ctx.tender.id %>');
     </script>
 <% } %>
-<script>const cur_uid = parseInt('<%- ctx.session.sessionUser.accountId %>');</script>
+
+<script>
+    const cur_uid = parseInt('<%- ctx.session.sessionUser.accountId %>');
+    const cur_tenderid = parseInt('<%- ctx.tender.id %>');
+</script>
 <script>
     $('.sp-location-list').on('shown.bs.modal', function () {
         const scrollBox = $(this).find('div[class="col-8 modal-height-500"]');
@@ -1071,3 +1074,376 @@
         });
     });
 </script>
+<% if (ctx.session.sessionUser.accountId === ctx.material.user_id && (ctx.material.calc_stage !== ctx.material.stage_id || !ctx.material.calc_tp)) { %>
+    <div class="modal fade" id="okedit" data-backdrop="static">
+        <div class="modal-dialog " role="document" >
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">生成新一期调差清单</h5>
+                </div>
+                <div class="modal-body">
+                    <div>
+                        <h5 id="material-detail">正在获取上期调差清单数据中,请等待...</h5>
+                        <div class="progress">
+                            <div id="material-progress" class="progress-bar" role="progressbar" style="width: 100%;" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">100%</div>
+                        </div>
+                    </div>
+                    <% if (ctx.material.is_stage_self) { %>
+                        <% for (const ms of materialStageData) { %>
+                        <div id="list-detail-<%- ms.sid %>" style="display: none" class="mt-3">
+                            <h5>生成期调差清单:<b>第<%- ms.order %>期</b></h5>
+                            <div class="progress">
+                                <div id="list-progress-<%- ms.sid %>" class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
+                            </div>
+                        </div>
+                        <% } %>
+                    <% } else { %>
+                    <div id="list-detail" style="display: none" class="mt-3">
+                        <h5>生成调差清单:</h5>
+                        <div class="progress">
+                            <div id="list-progress" class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
+                        </div>
+                    </div>
+                    <% } %>
+                    <div id="self-detail" style="display: none" class="mt-3">
+                        <h5>处理独立调差清单和计算总金额:</h5>
+                        <div class="progress">
+                            <div id="self-progress" class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
+                        </div>
+                    </div>
+                </div>
+                <div class="modal-footer" style="display: none" id="reload-make">
+                    <button type="button" class="btn btn-sm btn-primary" onclick="window.location.reload();">刷新页面</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    <script>
+        $(function () {
+            const stage_ids = JSON.parse(unescape('<%- escape(JSON.stringify(ctx.material.stage_id)) %>'));
+            const calc_stages = JSON.parse(unescape('<%- escape(JSON.stringify(ctx.material.calc_stage)) %>'));
+            const stage_id = stage_ids.split(',');
+            const calc_stage = calc_stages.split(',');
+            const calc_tp = parseInt('<%- ctx.material.calc_tp %>');
+            // stage_id和calc_stage数组对比,找出不同的值,并发起更新
+            const diff_stage_ids = _.difference(stage_id, calc_stage);
+            if (diff_stage_ids.length === 0 && calc_tp) return;
+            const is_stage_self = parseInt('<%- ctx.material.is_stage_self %>');
+            $('#okedit').modal('show');
+            let value = 0;
+            let interval;
+            let stop = false;
+            setProgress($('#material-progress'), 30);
+            postData('/tender/'+ cur_tenderid +'/measure/material/gcl/load', { stage_id, is_stage_self }, async function (result) {
+                // console.log(result);
+                const ledger = result.ledger;
+                const pos = result.pos;
+                const gclList = result.gclList;
+                const selfList = result.selfList;
+                // 整理material,针对上期是独立单价并多个不同值的单独设置值进行部分值去除
+                const materialListForSelf = _.uniqWith(_.orderBy(result.materialListForSelf, ['ms_id'], ['desc']), function(item1, item2) {
+                    return item1.xmj_id === item2.xmj_id && item1.gcl_id === item2.gcl_id && item1.mx_id === item2.mx_id && item1.mb_id === item2.mb_id;
+                });
+                const insertSelfList = [];// 需要单独添加的明细清单工料含量列表
+                const hadQtySelfList = [];
+                $('#material-detail').text('获取上期调差清单数据成功');
+                stopProgress($('#material-progress'));
+                if (is_stage_self) {
+                    for (const [i, newSid] of diff_stage_ids.entries()) {
+                        const sid = parseInt(newSid);
+                        $('#list-detail-' + sid).show();
+                        resetProgress($('#list-progress-' + sid));
+                        if (!interval) {
+                            $('#list-detail-' + sid).show();
+                            setProgress($('#list-progress-' + sid), 30);
+                        }
+                        const insertGclList = [];
+                        const insertList = [];
+                        const removeGclList = [];
+                        const curLedger = _.find(result.curLedgerData, {sid: newSid});
+                        const curPos = _.find(result.curPosData, {sid: newSid});
+                        gclGatherModel.loadLedgerData(_.cloneDeep(ledger), curLedger.ledgerData);
+                        gclGatherModel.loadPosData(_.cloneDeep(pos), curPos.posData);
+                        const gclGatherData = gclGatherModel.gatherGclData();
+                        // console.log(gclGatherData);
+                        const insertGcl = [];
+                        for (const g of gclList) {
+                            const gcl = _.find(gclGatherData, function (item) {
+                                return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: g.gcl_id}) !== -1;
+                            });
+                            if (gcl) {
+                                const ig = _.find(insertGcl, {gcl});
+                                if (ig) {
+                                    if (_.findIndex(ig.bills, {mb_id: g.mb_id}) === -1) {
+                                        ig.bills.push(g);
+                                    }
+                                } else {
+                                    insertGcl.push({
+                                        bills: [g],
+                                        gcl,
+                                        leafXmjs: _.filter(gcl.leafXmjs, function (item) {
+                                            return item.gather_qty !== undefined && item.gather_qty !== null
+                                        }),
+                                    })
+                                }
+                            } else {
+                                removeGclList.push(g);
+                            }
+                        }
+                        for (const one of insertGcl) {
+                            if (one.leafXmjs && one.leafXmjs.length > 0) {
+                                for (const xmj of one.leafXmjs) {
+                                    const is_self = _.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : '' }) !== -1;// 区分单独计量的明细工料含量
+                                    if (is_self) {
+                                        const billsList = _.filter(materialListForSelf, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : '' });
+                                        for (const bill of billsList) {
+                                            if (!_.find(hadQtySelfList, bill)) {
+                                                hadQtySelfList.push(bill);
+                                            }
+                                            insertSelfList.push({
+                                                gcl_id: xmj.gcl_id,
+                                                mx_id: xmj.mx_id ? xmj.mx_id : '',
+                                                xmj_id: xmj.id ? xmj.id : null,
+                                                contract_qty: xmj.contract_qty,
+                                                qc_qty: xmj.qc_qty,
+                                                qc_minus_qty: xmj.qc_minus_qty,
+                                                gather_qty: xmj.gather_qty,
+                                                quantity: bill.quantity,
+                                                expr: bill.expr,
+                                                mb_id: bill.mb_id,
+                                                order: bill.order,
+                                                sid,
+                                            });
+                                        }
+                                    } else {
+                                        const newgcl = _.find(gclList, { gcl_id: xmj.gcl_id });
+                                        for (const bill of one.bills) {
+                                            insertList.push({
+                                                gcl_id: xmj.gcl_id,
+                                                mx_id: xmj.mx_id ? xmj.mx_id : '',
+                                                xmj_id: xmj.id ? xmj.id : null,
+                                                contract_qty: xmj.contract_qty,
+                                                qc_qty: xmj.qc_qty,
+                                                qc_minus_qty: xmj.qc_minus_qty,
+                                                gather_qty: xmj.gather_qty,
+                                                quantity: bill.quantity,
+                                                expr: bill.expr,
+                                                mb_id: bill.mb_id,
+                                                order: bill.order,
+                                                sid,
+                                            });
+                                            if (!newgcl) {
+                                                if (_.findIndex(insertGclList, { gcl_id: xmj.gcl_id }) === -1) {
+                                                    insertGclList.push({
+                                                        gcl_id: xmj.gcl_id,
+                                                        quantity: bill.quantity,
+                                                        expr: bill.expr,
+                                                        old_quantity: bill.quantity,
+                                                        old_expr: bill.expr,
+                                                        mb_id: bill.mb_id,
+                                                        order: bill.order,
+                                                    });
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        console.log(sid, insertList, insertGclList, removeGclList);
+                        const msg = await postMLData(sid, insertList, insertGclList, removeGclList, $('#list-progress-' + sid));
+                        if (!msg) return;
+                    }
+                } else {
+                    $('#list-detail').show();
+                    resetProgress($('#list-progress'));
+                    if (!interval) {
+                        $('#list-detail').show();
+                        setProgress($('#list-progress'), 30);
+                    }
+                    const insertGclList = [];
+                    const insertList = [];
+                    const removeGclList = [];
+                    const curLedgerData = result.curLedgerData;
+                    const curPosData = result.curPosData;
+                    gclGatherModel.loadLedgerData(_.cloneDeep(ledger), curLedgerData);
+                    gclGatherModel.loadPosData(_.cloneDeep(pos), curPosData);
+                    const gclGatherData = gclGatherModel.gatherGclData();
+                    const insertGcl = [];
+                    for (const g of gclList) {
+                        const gcl = _.find(gclGatherData, function (item) {
+                            return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, {gcl_id: g.gcl_id}) !== -1;
+                        });
+                        if (gcl) {
+                            const ig = _.find(insertGcl, {gcl});
+                            if (ig) {
+                                if (_.findIndex(ig.bills, {mb_id: g.mb_id}) === -1) {
+                                    ig.bills.push(g);
+                                }
+                            } else {
+                                insertGcl.push({
+                                    bills: [g],
+                                    gcl,
+                                    leafXmjs: _.filter(gcl.leafXmjs, function (item) {
+                                        return item.gather_qty !== undefined && item.gather_qty !== null || (item.qc_minus_qty !== undefined && item.qc_minus_qty !== null)
+                                    }),
+                                })
+                            }
+                        } else {
+                            removeGclList.push(g);
+                        }
+                    }
+                    for (const one of insertGcl) {
+                        if (one.leafXmjs && one.leafXmjs.length > 0) {
+                            for (const xmj of one.leafXmjs) {
+                                const is_self = _.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null }) !== -1;// 区分单独计量的明细工料含量
+                                if (is_self) {
+                                    const billsList = _.filter(materialListForSelf, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null });
+                                    for (const bill of billsList) {
+                                        hadQtySelfList.push(bill);
+                                        insertSelfList.push({
+                                            gcl_id: xmj.gcl_id,
+                                            mx_id: xmj.mx_id ? xmj.mx_id : '',
+                                            xmj_id: xmj.id ? xmj.id : null,
+                                            contract_qty: xmj.contract_qty,
+                                            qc_qty: xmj.qc_qty,
+                                            qc_minus_qty: xmj.qc_minus_qty,
+                                            gather_qty: xmj.gather_qty,
+                                            quantity: bill.quantity,
+                                            expr: bill.expr,
+                                            mb_id: bill.mb_id,
+                                            order: bill.order,
+                                        });
+                                    }
+                                } else {
+                                    const newgcl = _.find(gclList, { gcl_id: xmj.gcl_id });
+                                    for (const bill of one.bills) {
+                                        insertList.push({
+                                            gcl_id: xmj.gcl_id,
+                                            mx_id: xmj.mx_id ? xmj.mx_id : '',
+                                            xmj_id: xmj.id ? xmj.id : null,
+                                            contract_qty: xmj.contract_qty,
+                                            qc_qty: xmj.qc_qty,
+                                            qc_minus_qty: xmj.qc_minus_qty,
+                                            gather_qty: xmj.gather_qty,
+                                            quantity: bill.quantity,
+                                            expr: bill.expr,
+                                            mb_id: bill.mb_id,
+                                            order: bill.order,
+                                        });
+                                        if (!newgcl) {
+                                            insertGclList.push({
+                                                gcl_id: xmj.gcl_id,
+                                                quantity: bill.quantity,
+                                                expr: bill.expr,
+                                                old_quantity: bill.quantity,
+                                                old_expr: bill.expr,
+                                                mb_id: bill.mb_id,
+                                                order: bill.order,
+                                            });
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    console.log(diff_stage_ids, insertList, insertGclList, removeGclList);
+                    const msg = await postMLData(diff_stage_ids.join(','), insertList, insertGclList, removeGclList, $('#list-progress'));
+                    if (!msg) return;
+                }
+                $('#self-detail').show();
+                setProgress($('#self-progress'), 30);
+                // 通过比较materialListForSelf和hadQtySelfList不重合部分,得出本期为null的gather_qty列表,插入到insertSelfList中
+                const pushSelfList = _.xorWith(materialListForSelf, hadQtySelfList, _.isEqual);
+                if (pushSelfList.length > 0) {
+                    for (const ps of pushSelfList) {
+                        insertSelfList.push({
+                            gcl_id: ps.gcl_id,
+                            mx_id: ps.mx_id,
+                            xmj_id: ps.xmj_id,
+                            contract_qty: null,
+                            qc_qty: null,
+                            qc_minus_qty: null,
+                            gather_qty: null,
+                            quantity: ps.quantity,
+                            expr: ps.expr,
+                            mb_id: ps.mb_id,
+                            order: ps.order,
+                        });
+                    }
+                }
+                console.log(insertSelfList);
+                postData('/tender/' + cur_tenderid + '/measure/material/save/data', { type: 'make_self_list', mid: materialID || mid, material_self_list: insertSelfList }, function (result) {
+                    stopProgress($('#self-progress'));
+                    $('#reload-make').show();
+                }, function (err) {
+                    stop = true;
+                    clearInterval(interval);
+                    $('#reload-make').show();
+                });
+
+                // postData(preUrl + '/measure/material/add', newMaterialData, function (result) {
+                //     window.location.href = preUrl + '/measure/material/' + result.order;
+                // }, function () {
+                //     stop = true;
+                //     clearInterval(interval);
+                //     console.log(_self.parents('div[id="add-qi"]'));
+                //     $('#add-qi').modal('show');
+                //     $('#okedit').modal('hide');
+                //     _self.parents('div[id="add-qi"]').modal('show');
+                //     _self.attr('disabled', false).text('确认添加');
+                // });
+                return;
+            });
+
+            async function postMLData(stage_id, material_list, insertGclList, removeGclList, _progress) {
+                try {
+                    const result = await postDataAsync('/tender/' + cur_tenderid + '/measure/material/save/data', { type: 'make_material_list', mid: materialID || mid, stage_id, material_list, insertGclList, removeGclList });
+                    if (!result) {
+                        stop = true;
+                        clearInterval(interval);
+                        $('#reload-make').show();
+                    } else {
+                        stopProgress(_progress);
+                    }
+                    return result ? result : false;
+                } catch (err) {
+                    console.error('失败:', err);
+                    stop = true;
+                    clearInterval(interval);
+                    $('#reload-make').show();
+                    return false;
+                }
+            }
+
+
+            function setProgress(_this, time = 50) {
+                interval = setInterval(function () {
+                    if (value < 100) {
+                        value = parseInt(value) + 1;
+                        _this.css("width", value + "%").text(value + "%");
+                    } else if (value === 100) {
+                        value = parseInt(value) + 1;
+                        value = 30;
+                    }
+                }, time);
+            }
+
+            function resetProgress(_this) {
+                _this.removeClass('bg-success');
+                _this.css("width", "0%").text("0%").attr('aria-valuenow', '0');
+            }
+
+            function stopProgress(_this) {
+                if (interval) {
+                    _this.addClass('bg-success');
+                    _this.css("width", "100%").text("100%");
+                    value = 0;
+                    stop = true;
+                    clearInterval(interval);
+                    interval = 0;
+                }
+            }
+        })
+    </script>
+<% } %>

+ 5 - 0
sql/update.sql

@@ -14,6 +14,11 @@ ADD COLUMN `tp_cache_time` timestamp NULL COMMENT '缓存时间' AFTER `tp_cache
 ALTER TABLE `zh_contract_audit`
 ADD COLUMN `permission_att` tinyint(1) NULL DEFAULT 0 COMMENT '上传附件' AFTER `permission_show_node`;
 
+ALTER TABLE `zh_material`
+ADD COLUMN `calc_stage` varchar(255) NULL DEFAULT '' COMMENT '用于生成期工料含量数据,期创建后使用' AFTER `final_auditor_str`,
+COLUMN `calc_tp` tinyint(1) NULL DEFAULT 1 COMMENT '用于判断是否已计算总金额,期创建后使用' AFTER `calc_stage`;
+
 ------------------------------------
 -- 表数据
 ------------------------------------
+update `zh_material` set `calc_stage` = `stage_id` where `calc_stage` = '';