瀏覽代碼

调差清单设置 no.2 up

laiguoran 3 年之前
父節點
當前提交
dffa8e9184

+ 1 - 0
app/const/account_permission.js

@@ -29,6 +29,7 @@ const permission = {
             { title: '创建标段', value: 1 },
             { title: '查阅所有标段', value: 2 },
             { title: '维护签约清单', value: 3, hint: '开启该选项,台账审批通过后,可上传签约清单', hintIcon: 'fa-question-circle' },
+            { title: '材差清单设置', value: 4, hint: '开启该选项,当前账号可设置允许调差的清单', hintIcon: 'fa-question-circle' },
         ],
     },
     // cooperation: {

+ 25 - 2
app/controller/material_controller.js

@@ -592,6 +592,9 @@ module.exports = app => {
                     msg: '',
                     data: {},
                 };
+                if (ctx.session.sessionProject.page_show.openMaterialChecklist && (data.type !== 'join' && data.type !== 'notjoin')) {
+                    throw '清单设置功能已启动,请前往清单设置页操作清单内容';
+                }
                 switch (data.type) {
                     case 'add':
                         responseData.data = await ctx.service.materialList.add(data.postData);
@@ -1225,6 +1228,17 @@ module.exports = app => {
             }
         }
 
+        async _setChecklistPermission(ctx) {
+            // 清单设置权限判断
+            ctx.material.checklistPermission = false;
+            if (ctx.session.sessionProject.page_show.openMaterialChecklist && ctx.material.highOrder === ctx.material.order && ctx.material.status !== auditConst.status.checked) {
+                const permission = ctx.session.sessionUser.permission;
+                if ((ctx.material.order === 1 && ctx.session.sessionUser.accountId === ctx.material.user_id) || (permission.tender !== undefined && permission.tender.indexOf('4') !== -1)) {
+                    ctx.material.checklistPermission = true;
+                }
+            }
+        }
+
         /**
          * 清单设置页
          * @param {Object} ctx - 全局上下文
@@ -1232,6 +1246,8 @@ module.exports = app => {
         async checklist(ctx) {
             try {
                 await this._getMaterialAuditViewData(ctx);
+                await this._setChecklistPermission(ctx);
+                ctx.material.readOnly = !ctx.material.checklistPermission;
                 const renderData = await this._getDefaultRenderData(ctx);
                 // 根据期判断需要获取的工料信息值表
                 const searchsql = { tid: ctx.tender.id };
@@ -1274,7 +1290,7 @@ module.exports = app => {
         }
 
         /**
-         * 指数调差 - 编辑指数清单项 (Ajax)
+         * 清单设置 - 编辑指数清单项 (Ajax)
          * @param ctx
          * @return {Promise<void>}
          */
@@ -1286,7 +1302,14 @@ module.exports = app => {
                     msg: '',
                     data: {},
                 };
-                console.log(data);
+                await this._setChecklistPermission(ctx);
+                if (ctx.material.order !== ctx.material.highOrder) {
+                    throw '无法设置非最新期的清单设置数据';
+                }
+                // 权限控制
+                if (!ctx.material.checklistPermission) {
+                    throw '本期已审批完成或权限不足,无法设置清单数据';
+                }
                 switch (data.type) {
                     case 'adds':
                         responseData.data = await ctx.service.materialList.adds(data.postData, data.checklist);

+ 3 - 0
app/middleware/material_check.js

@@ -163,6 +163,9 @@ module.exports = options => {
                 }));
             }
             // 重定向值标段管理
+            if (err === '您无权查看该数据') {
+                this.tender ? this.redirect('/tender/' + this.tender.id + '/measure/material') : this.redirect('/list');
+            }
             this.redirect(this.request.headers.referer);
         }
     };

+ 24 - 18
app/public/js/material_checklist.js

@@ -35,7 +35,7 @@ function makeChecklistData(lists, checklists) {
     let html = '';
     if (lists.length > 0) {
         for(const [i,l] of lists.entries()) {
-            const checklistInfo = _.find(checklists, { b_code: l.b_code, name: l.name, unit: l.unit, unit_price: l.unit_price, quantity: l.quantity });
+            const checklistInfo = _.find(checklists, { b_code: l.b_code, name: l.name, unit: l.unit, unit_price: l.unit_price });
             const isChecked = checklistInfo ? ' checked' : '';
             const isDisabled = checklistInfo && checklistInfo.had_bills === 1 ? ' disabled' : '';
             html += '<tr>\n' +
@@ -46,10 +46,10 @@ function makeChecklistData(lists, checklists) {
                 '                                    <td class="text-center">'+ (i+1) +'</td>\n' +
                 '                                    <td>'+ l.b_code +'</td>\n' +
                 '                                    <td>'+ l.name +'</td>\n' +
-                '                                    <td class="text-center">'+ l.unit +'</td>\n' +
-                '                                    <td class="text-right">'+ l.unit_price +'</td>\n' +
-                '                                    <td class="text-right">'+ l.quantity +'</td>\n' +
-                '                                    <td class="text-right">'+ l.total_price +'</td>\n' +
+                '                                    <td class="text-center">'+ (l.unit ? l.unit : '') +'</td>\n' +
+                '                                    <td class="text-right">'+ (l.unit_price ? l.unit_price : '') +'</td>\n' +
+                '                                    <td class="text-right">'+ (l.quantity ? l.quantity : '') +'</td>\n' +
+                '                                    <td class="text-right">'+ (l.total_price ? l.total_price : '') +'</td>\n' +
                 '                                </tr>';
         }
     }
@@ -136,27 +136,26 @@ $(document).ready(() => {
         // 解析清单汇总数据
         gclGatherModel.loadLedgerData(ledger, curLedgerData);
         gclGatherModel.loadPosData(pos, curPosData);
-        gclGatherData = gclGatherModel.gatherGclData().filter(item => {
-            return item.qc_qty || item.contract_qty
-        });
+        gclGatherData = gclGatherModel.gatherGclData();
         console.log(gclGatherData);
         const hadBillsidList = _.uniq(_.map(materialListData, 'gcl_id'));
-        const pushData = [];
         // 对比清单设置和调差清单,还要和台账对比,显示已选清单列表 不同则更新到清单设置页中
+        const pushData = [];
         for (const hb of hadBillsidList) {
             const gcl = _.find(gclGatherData, function (item) {
                 return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, { gcl_id : hb }) !== -1;
             });
             if (gcl) {
-                const mc = _.find(materialChecklistData, { b_code: gcl.b_code, name: gcl.name, unit: gcl.unit, unit_price: gcl.unit_price, quantity: gcl.quantity });
-                if (!mc) {
-                    pushData.push({ order: _.indexOf(gclGatherData, gcl), b_code: gcl.b_code, name: gcl.name, unit: gcl.unit, unit_price: gcl.unit_price, quantity: gcl.quantity, total_price: gcl.total_price, had_bills: 1 })
+                const mc = _.find(materialChecklistData, { b_code: gcl.b_code, name: gcl.name, unit: gcl.unit, unit_price: gcl.unit_price });
+                const newOrder = _.indexOf(gclGatherData, gcl);
+                if (!mc && _.findIndex(pushData, { order: newOrder }) === -1) {
+                    pushData.push({ b_code: gcl.b_code, name: gcl.name, unit: gcl.unit, unit_price: gcl.unit_price, quantity: (gcl.quantity ? gcl.quantity : null), total_price: (gcl.total_price ? gcl.total_price : null), had_bills: 1 });
                 }
             }
         }
         const removeData = [];
         for (const mc of materialChecklistData) {
-            const gcl = _.find(gclGatherData, { b_code: mc.b_code, name: mc.name, unit: mc.unit, unit_price: mc.unit_price, quantity: mc.quantity });
+            const gcl = _.find(gclGatherData, { b_code: mc.b_code, name: mc.name, unit: mc.unit, unit_price: mc.unit_price });
             // 判断是否已不存在工料清单,台账修改过后删除之
             if (!gcl) {
                 removeData.push(mc.id);
@@ -185,6 +184,8 @@ $(document).ready(() => {
         SpreadJsObj.resetTopAndSelect(ledgerSpread.getActiveSheet());
         if (materialChecklistData.length > 0) {
             loadMaterialData(materialChecklistData[0].order, 0);
+        } else {
+            loadMaterialData(-1, 0);
         }
         const sheet = materialSpread.getActiveSheet();
         sheet.suspendPaint();
@@ -231,16 +232,21 @@ $(document).ready(() => {
         if (gcl && gcl.leafXmjs[iLXmjRow]) {
             const xmj = gcl.leafXmjs[iLXmjRow];
             materialList = [];
-            for (const m of materialListData) {
-                if (m.gcl_id === xmj.gcl_id && m.xmj_id === xmj.id && ((xmj.mx_id !==undefined && m.mx_id === xmj.mx_id) || xmj.mx_id === undefined)) {
-                    materialList.push(m);
-                }
-            }
+            materialList = _.filter(materialListData, function (m) {
+                return m.gcl_id === xmj.gcl_id && m.xmj_id === xmj.id && ((xmj.mx_id !==undefined && m.mx_id === xmj.mx_id) || xmj.mx_id === undefined);
+            });
+            // for (const m of materialListData) {
+            //     if (m.gcl_id === xmj.gcl_id && m.xmj_id === xmj.id && ((xmj.mx_id !==undefined && m.mx_id === xmj.mx_id) || xmj.mx_id === undefined)) {
+            //         materialList.push(m);
+            //     }
+            // }
             // 对清单调差工料table的单位数量进行改变
             materialSpreadSetting.cols[materialSpreadSetting.cols.length - 2].title = '|' + gcl.unit + '数量 �';
             SpreadJsObj.initSheet(materialSpread.getActiveSheet(), materialSpreadSetting);
             SpreadJsObj.loadSheetData(materialSpread.getActiveSheet(), SpreadJsObj.DataType.Data, materialList);
         } else {
+            materialSpreadSetting.cols[materialSpreadSetting.cols.length - 2].title = '数量 �';
+            SpreadJsObj.initSheet(materialSpread.getActiveSheet(), materialSpreadSetting);
             SpreadJsObj.loadSheetData(materialSpread.getActiveSheet(), SpreadJsObj.DataType.Data, []);
         }
         SpreadJsObj.resetTopAndSelect(materialSpread.getActiveSheet());

+ 86 - 57
app/public/js/material_list.js

@@ -209,12 +209,19 @@ $(document).ready(() => {
         curPosData = result.curPosData;
         materialListData = result.materialListData;
         notJoinList = result.materialNotJoinListData;
+        materialChecklistData = result.materialChecklistData;
         // 解析清单汇总数据
         gclGatherModel.loadLedgerData(ledger, curLedgerData);
         gclGatherModel.loadPosData(pos, curPosData);
         gclGatherData = gclGatherModel.gatherGclData().filter(item => {
             return item.qc_qty || item.contract_qty
         });
+        if (openMaterialChecklist) {
+            // 取交集
+            gclGatherData = _.filter(gclGatherData, function (item) {
+                return _.find(materialChecklistData, { b_code: item.b_code, name: item.name, unit: item.unit, unit_price: item.unit_price });
+            });
+        }
         calculateJiaCha(gclGatherData);
         SpreadJsObj.initSheet(leafXmjSpread.getActiveSheet(), leafXmjSpreadSetting);
         // 加载清单数据
@@ -266,7 +273,7 @@ $(document).ready(() => {
     const materialBase = {
         isEdit: function (data) {
             // 是否本期添加的工料
-            return data.order === stage_order;
+            return data.order === stage_order && !openMaterialChecklist;
         }
     };
 
@@ -286,6 +293,11 @@ $(document).ready(() => {
     let materialList = [];
     function loadMaterialData(iGclRow, iLXmjRow) {
         const gcl = gclGatherData[iGclRow];
+        // const leafXmjs = gcl.leafXmjs.filter(item => {
+        //     return item.qc_qty || item.contract_qty
+        // });
+        // console.log(iLXmjRow, leafXmjs, materialListData);
+        console.log(iGclRow, gcl.leafXmjs);
         if (gcl && gcl.leafXmjs[iLXmjRow]) {
             const xmj = gcl.leafXmjs[iLXmjRow];
             materialList = [];
@@ -294,6 +306,7 @@ $(document).ready(() => {
                     materialList.push(m);
                 }
             }
+            console.log(materialList);
             SpreadJsObj.loadSheetData(materialSpread.getActiveSheet(), SpreadJsObj.DataType.Data, materialList);
         } else {
             SpreadJsObj.loadSheetData(materialSpread.getActiveSheet(), SpreadJsObj.DataType.Data, []);
@@ -314,7 +327,9 @@ $(document).ready(() => {
         const select = SpreadJsObj.getSelectObject(sheet);
         const index = gclGatherData.indexOf(select);
         if (index !== -1) {
-            const xmj = gclGatherData[index].leafXmjs;
+            const xmj = gclGatherData[index].leafXmjs.filter(item => {
+                return item.qc_qty || item.contract_qty
+            });
             const leafXmjSheet = leafXmjSpread.getActiveSheet();
             for (const [iRow,x] of xmj.entries()) {
                 const notx = findNotJoinLeafXmj(x);
@@ -416,15 +431,21 @@ $(document).ready(() => {
                 const leafXmjSheet = leafXmjSpread.getActiveSheet();
                 const leafXmjSelect = SpreadJsObj.getSelectObject(leafXmjSheet);
                 const iRow = gclGatherData[index].leafXmjs.indexOf(leafXmjSelect);
-                return [index, iRow, leafXmjSheet, leafXmjSelect];
+                const leafXmjs = gclGatherData[index].leafXmjs.filter(item => {
+                    return item.qc_qty || item.contract_qty
+                });
+                const nRow = leafXmjs.indexOf(leafXmjSelect);
+                return [index, iRow, nRow, leafXmjSheet, leafXmjSelect];
             },
             checkJoinMaterial: function (type) {
-                const [iGclRow, iRow, sheet, select] = leafXmjSpreadObj.getSelect();
+                const [iGclRow, iRow, nRow, sheet, select] = leafXmjSpreadObj.getSelect();
                 const color = type === 'join' ? '' : '#d6d8db';
                 const data = {
                     type: type,
                     select: type === 'join' ? findNotJoinLeafXmj(select) : select,
-                }
+                };
+                console.log(iGclRow, iRow, nRow, select);
+                console.log(materialList);
                 // 添加到
                 postData(window.location.pathname + '/save', data, function (result) {
                     if (type === 'join') {
@@ -434,10 +455,10 @@ $(document).ready(() => {
                         notJoinList.push(result);
                     }
                     gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(select);
-                    calculateJiaCha(gclGatherData, iGclRow)
-                    SpreadJsObj.reLoadRowData(sheet, iRow);
-                    sheet.getRange(iRow, -1, 1, -1).backColor(color);
-                    loadMaterialData(iGclRow, iRow);
+                    calculateJiaCha(gclGatherData, iGclRow);
+                    SpreadJsObj.reLoadRowData(sheet, nRow);
+                    sheet.getRange(nRow, -1, 1, -1).backColor(color);
+                    loadMaterialData(iGclRow, 0);
                     SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
                 });
             },
@@ -930,57 +951,59 @@ $(document).ready(() => {
             //     SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), index);
             // });
         });
-        $.contextMenu({
-            selector: '#material-spread',
-            build: function ($trigger, e) {
-                const target = SpreadJsObj.safeRightClickSelection($trigger, e, materialSpread);
-                return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
-            },
-            items: {
-                'create': {
-                    name: '添加工料',
-                    icon: 'fa-sign-in',
-                    callback: function (key, opt) {
-                        // 获取已选清单
-                        changeMaterialTable();
-                        $('#addgl').modal('show');
-                    },
-                    disabled: function (key, opt) {
-                        const sheet = leafXmjSpread.getActiveSheet();
-                        const select = SpreadJsObj.getSelectObject(sheet);
-                        // const notx = findNotJoinLeafXmj(select);
-                        if (!select) {
-                            return true;
-                        }
-                        // if (!readOnly && notx === undefined) {
-                        //     return false;
-                        // } else {
-                        //     return true;
-                        // }
-                        return readOnly;
-                    }
+        if (!openMaterialChecklist) {
+            $.contextMenu({
+                selector: '#material-spread',
+                build: function ($trigger, e) {
+                    const target = SpreadJsObj.safeRightClickSelection($trigger, e, materialSpread);
+                    return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
                 },
-                'delete': {
-                    name: '删除工料',
-                    icon: 'fa-remove',
-                    callback: function (key, opt) {
-                        materialSpreadObj.del(materialSpread.getActiveSheet());
-                    },
-                    disabled: function (key, opt) {
-                        const sheet = materialSpread.getActiveSheet();
-                        const select = SpreadJsObj.getSelectObject(sheet);
-                        if (!select) {
-                            return true;
+                items: {
+                    'create': {
+                        name: '添加工料',
+                        icon: 'fa-sign-in',
+                        callback: function (key, opt) {
+                            // 获取已选清单
+                            changeMaterialTable();
+                            $('#addgl').modal('show');
+                        },
+                        disabled: function (key, opt) {
+                            const sheet = leafXmjSpread.getActiveSheet();
+                            const select = SpreadJsObj.getSelectObject(sheet);
+                            // const notx = findNotJoinLeafXmj(select);
+                            if (!select) {
+                                return true;
+                            }
+                            // if (!readOnly && notx === undefined) {
+                            //     return false;
+                            // } else {
+                            //     return true;
+                            // }
+                            return readOnly;
                         }
-                        if (!readOnly && select && materialBase.isEdit(select)) {
-                            return false;
-                        } else {
-                            return true;
+                    },
+                    'delete': {
+                        name: '删除工料',
+                        icon: 'fa-remove',
+                        callback: function (key, opt) {
+                            materialSpreadObj.del(materialSpread.getActiveSheet());
+                        },
+                        disabled: function (key, opt) {
+                            const sheet = materialSpread.getActiveSheet();
+                            const select = SpreadJsObj.getSelectObject(sheet);
+                            if (!select) {
+                                return true;
+                            }
+                            if (!readOnly && select && materialBase.isEdit(select)) {
+                                return false;
+                            } else {
+                                return true;
+                            }
                         }
-                    }
-                },
-            }
-        });
+                    },
+                }
+            });
+        }
     }
 
     // 切换清单行,读取所属项目节数据
@@ -1036,6 +1059,12 @@ $(document).ready(() => {
             gclGatherData = gclGatherModel.gatherGclData().filter(item => {
                 return item.qc_qty || item.contract_qty
             });
+            if (openMaterialChecklist) {
+                // 取交集
+                gclGatherData = _.filter(gclGatherData, function (item) {
+                    return _.find(materialChecklistData, { b_code: item.b_code, name: item.name, unit: item.unit, unit_price: item.unit_price });
+                });
+            }
         }
         calculateJiaCha(gclGatherData);
         SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gclGatherData);

+ 1 - 0
app/service/material_audit.js

@@ -355,6 +355,7 @@ module.exports = app => {
                     // 处理旧数据,防止重复插入到历史表
                     await transaction.delete(this.ctx.service.materialBillsHistory.tableName, { tid: this.ctx.tender.id, order: this.ctx.material.order});
                     const mbhList = [];
+                    const materialBillsData = await this.ctx.service.materialBills.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });
                     for (const mb of materialBillsData) {
                         if (mb.code === '') {
                             throw '调差工料编号不能为空';

+ 1 - 1
app/view/material/checklist_modal.ejs

@@ -66,7 +66,7 @@
                         <div class="mb-2 col-6 p-0 search-group"><input id="tclist_search" class="form-control form-control-sm" placeholder="输入 清单编号、名称 检索" value=""><a href="javascript:void(0);" style="display: none" class="text-danger remove-btn" title="移除关键词"><i class="fa fa-times-circle "></i></a></div>
                         <div style="overflow-y:auto" class="sjs-biangeng-height">
                             <table class="table table-striped table-bordered table-hover table-sm">
-                                <thead class="text-center"><tr><th width="40">选择</th><th width="40">序号</th><th>清单编号</th><th>名称</th><th width="50">单位</th><th width="100">单价</th><th width="100">数量</th><th width="100">金额</th></tr></thead>
+                                <thead class="text-center"><tr><th width="40">选择</th><th width="40">序号</th><th width="80">清单编号</th><th>名称</th><th width="50">单位</th><th width="100">单价</th><th width="100">数量</th><th width="100">金额</th></tr></thead>
                                 <tbody id="lists_data">
                                 </tbody>
                             </table>

+ 3 - 0
app/view/material/exponent.ejs

@@ -18,6 +18,9 @@
                 <!--</div>-->
             </div>
             <div class="ml-auto">
+                <% if (ctx.session.sessionProject.page_show.openMaterialChecklist && material.order === material.highOrder) { %>
+                    <a href="/tender/<%- ctx.tender.id %>/measure/material/<%- material.highOrder %>/checklist" class="btn btn-sm btn-outline-primary">清单设置</a>
+                <% } %>
                 <a href="#cc-digits" class="btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#cc-digits" data-placement="bottom" title="" >小数位数</a>
             </div>
         </div>

+ 3 - 0
app/view/material/file.ejs

@@ -35,6 +35,9 @@
           <!--</span>-->
         <!--</div>-->
       <div class="ml-auto">
+        <% if (ctx.session.sessionProject.page_show.openMaterialChecklist && material.order === material.highOrder) { %>
+          <a href="/tender/<%- ctx.tender.id %>/measure/material/<%- material.highOrder %>/checklist" class="btn btn-sm btn-outline-primary">清单设置</a>
+        <% } %>
         <a href="#cc-digits" class="btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#cc-digits" data-placement="bottom" title="" >小数位数</a>
       </div>
     </div>

+ 1 - 1
app/view/material/info.ejs

@@ -22,7 +22,7 @@
                 </div>
             </div>
             <div class="ml-auto">
-                <% if (material.order === material.highOrder) { %>
+                <% if (ctx.session.sessionProject.page_show.openMaterialChecklist && material.order === material.highOrder) { %>
                 <a href="/tender/<%- ctx.tender.id %>/measure/material/<%- material.highOrder %>/checklist" class="btn btn-sm btn-outline-primary">清单设置</a>
                 <% } %>
                 <a href="#cc-digits" class="btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#cc-digits" data-placement="bottom" title="" >小数位数</a>

+ 5 - 1
app/view/material/list.ejs

@@ -17,6 +17,9 @@
                 </div>
             </div>
             <div class="ml-auto">
+                <% if (ctx.session.sessionProject.page_show.openMaterialChecklist && material.order === material.highOrder) { %>
+                    <a href="/tender/<%- ctx.tender.id %>/measure/material/<%- material.highOrder %>/checklist" class="btn btn-sm btn-outline-primary">清单设置</a>
+                <% } %>
                 <a href="#cc-digits" class="btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#cc-digits" data-placement="bottom" title="" >小数位数</a>
             </div>
         </div>
@@ -77,5 +80,6 @@
     const stage_order = <%- material.order %>;
     const materialID = <%- material.id %>;
     const materialDecimal = JSON.parse(unescape('<%- escape(JSON.stringify(material.decimal)) %>'));
-    let materialListData, notJoinList, ledger, curLedgerData, pos, curPosData, gclGatherData;
+    const openMaterialChecklist = parseInt(<%- ctx.session.sessionProject.page_show.openMaterialChecklist %>);
+    let materialListData, materialChecklistData, notJoinList, ledger, curLedgerData, pos, curPosData, gclGatherData;
 </script>