Tony Kang 5 giờ trước cách đây
mục cha
commit
e1c1fd6b25

+ 35 - 11
app/controller/report_controller.js

@@ -1434,12 +1434,16 @@ module.exports = app => {
         async indexForCostManager(ctx, source_type, show_stage_id) {
             // 成本管理报表入口
             try {
-                // const ledge_stage_type = this.ctx.service.costStage.stageType.ledger.key;
-                // const ledge_stages = await this.getTypeStages(ctx, ledge_stage_type);
-                // const book_stage_type = this.ctx.service.costStage.stageType.book.key;
-                // const book_stages = await this.getTypeStages(ctx, book_stage_type);
+                const ledge_stage_type = this.ctx.service.costStage.stageType.ledger.key;
+                const ledge_stages = await this.getTypeStages(ctx, ledge_stage_type);
+                const book_stage_type = this.ctx.service.costStage.stageType.book.key;
+                const book_stages = await this.getTypeStages(ctx, book_stage_type);
                 const analysis_stage_type = this.ctx.service.costStage.stageType.analysis.key;
                 const analysis_stages = await this.getTypeStages(ctx, analysis_stage_type);
+                const all_cost_stages = {};
+                all_cost_stages.ledge = ledge_stages;
+                all_cost_stages.book = book_stages;
+                all_cost_stages.analysis = analysis_stages;
                 // await this._getCostManagerViewData(ctx);
                 // 普通报表界面需要的信息
                 const pageShow = ctx.session.sessionProject.page_show;
@@ -1448,9 +1452,6 @@ module.exports = app => {
                 pageShow.closeShowAllCustomized = 0;
                 // const tenderId = ctx.params.tid || -1; // 标段级别有
                 const tenderId = ctx.params.tid || -1;
-                const bglObj = {};
-                // const bglObj = { status: stage_status };
-                bglObj.BUSINESS_ID = ctx.params.id;
                 // cost_stage_id: uuid
                 const stage = analysis_stages[0]; // 默认取最新的cost- analysis stage
                 const stage_order = stage.stage_order;
@@ -1458,6 +1459,11 @@ module.exports = app => {
                 const stage_times = stage.audit_times;
                 // const stage_status = -1;
                 const stage_status = stage.audit_status;
+
+                const bglObj = { source_type, BUSINESS_ID: stage.id, status: stage_status, allStages: all_cost_stages };
+                // const bglObj = { status: stage_status };
+                // bglObj.BUSINESS_ID = ctx.params.id;
+
                 const project_id = ctx.subProject.id;
                 // const { treeNodes, custCfg, commonArrs } = await this._createNodes(ctx, sourceTypeConst.sourceType.contract, project_id);
                 const { treeNodes, custCfg, commonArrs, allTreeItems, allIndivTreeItems } = await this._createNodes(ctx, source_type, project_id);
@@ -1501,6 +1507,9 @@ module.exports = app => {
                     reportConst.rptCustomType[JV.NODE_CUS_CHANGE_SELECT], tenderId, -1);
                 customSelects.material_sum_select = await ctx.service.rptCustomDefine.getCustomSelectByRpt(cid,
                     reportConst.rptCustomType[JV.NODE_CUS_MATERIAL_SUM_SELECT], tenderId, -1);
+                const dataSelects = {};
+                dataSelects.material_select = await ctx.service.rptCustomDefine.getDataSelectByRpt(cid,
+                    reportConst.rptDataType[JV.NODE_CUS_MATERIAL_SELECT]);
 
 
                 const renderData = {
@@ -1547,7 +1556,7 @@ module.exports = app => {
                     materialAdjAuditList: JSON.stringify([]),
                     materialList: [],
                     stages: [],
-                    dataSelects: {},
+                    dataSelects,
                     pageShow,
                     // authMobile: accountInfo.auth_mobile,
                     shenpiConst,
@@ -1577,7 +1586,7 @@ module.exports = app => {
         }
 
         async indexForCostAnalysis(ctx) {
-            await this.indexForCostManager(ctx, sourceTypeConst.sourceType.cost_analysis, -800);
+            await this.indexForCostManager(ctx, sourceTypeConst.sourceType.cost_ledger, -800);
         }
 
         /**
@@ -1771,6 +1780,21 @@ module.exports = app => {
                         stageFlow.push({ aid: audit.audit_id, audit_type: audit.audit_type, status: audit.audit_status, order: audit.audit_order });
                     });
                     break;
+                case -800: // 成本报审
+                case -801: // 财务账面
+                case -802: // 成本分析
+                    const costAudit = await ctx.service.costStageAudit.getAuditors(params.cost_stage_id, params.stage_times);
+                    costAudit.forEach(audit => {
+                        stgAudit.push({ aid: audit.create_user_id, status: audit.audit_status, opinion: '', end_time: audit.audit_end_time, order: audit.stage_order });
+                        stageFlow.push({ aid: audit.create_user_id, audit_type: audit.stage_type, status: audit.audit_status, order: audit.stage_order });
+                    });
+                    break;
+                // case -801: // 财务账面
+                //     // const costStageAudit = await ctx.service.costStageAudit.getAuditors(params.business_id, params.stage_times);
+                //     break;
+                // case -802: // 成本分析
+                //     // const costStageAudit = await ctx.service.costStageAudit.getAuditors(params.business_id, params.stage_times);
+                //     break;
                 default:
                     break;
             }
@@ -1871,7 +1895,7 @@ module.exports = app => {
                     const payment = paymentDetailList[0];
                     stageList.push({ id: params.stage_id, user_id: payment.uid, status: payment.status });
                 }
-            } else if ([-150, -300, -301, -302, -303, -400, -500, -600, -700].includes(params.stage_id)) {
+            } else if ([-150, -300, -301, -302, -303, -400, -500, -600, -700, -800, -801, -802, -803].includes(params.stage_id)) {
                 // 变更令、预付款、材差相关的
                 stgAudit = [];
                 // stgAuditForOrg = [];
@@ -2005,7 +2029,7 @@ module.exports = app => {
                     const payment = paymentDetailList[0];
                     stageList.push({ id: params.stage_id, user_id: payment.uid, status: payment.status });
                 }
-            } else if ([-150, -300, -301, -302, -303, -400, -500, -600, -700].includes(params.stage_id)) {
+            } else if ([-150, -300, -301, -302, -303, -400, -500, -600, -700, -800, -801, -802, -803].includes(params.stage_id)) {
                 stgAudit = [];
                 stageFlow = [];
                 await this._commonGetAudit(ctx, params, stgAudit, stageFlow);

+ 12 - 0
app/public/report/js/rpt_main.js

@@ -533,6 +533,12 @@ let zTreeOprObj = {
             params.tid = params.tender_id;
             params.phase_pay_id = BUSINESS_ID;
         }
+        if ([-800, -801, -802, -803].includes(STAGE_ID)) {
+            url =  `/sp/${PROJECT_ID}/cost/tender/${TENDER_ID}/report_api/getReport`;
+            params.tid = params.tender_id;
+            params.id = PROJECT_ID;
+            params.cost_stage_id = BGL_OBJ.BUSINESS_ID;
+        }
         $.bootstrapLoading.start();
         CommonAjax.postXsrfEx(url, params, 300000, true, getCookie('csrfToken_j'),
             async function(result){
@@ -1308,6 +1314,12 @@ let rptControlObj = {
                     params.phase_pay_id = BUSINESS_ID;
                     url =  `/tender/${params.tid}/phase/report_api/getMultiReports`;
                 }
+                if ([-800, -801, -802, -803].includes(STAGE_ID)) {
+                    url =  `/sp/${PROJECT_ID}/cost/tender/${TENDER_ID}/report_api/getMultiReportsEx`;
+                    params.tid = params.tender_id;
+                    params.id = PROJECT_ID;
+                    params.cost_stage_id = BGL_OBJ.BUSINESS_ID;
+                }
                 CommonAjax.postXsrfEx(url, params, WAIT_TIME_EXPORT, true, getCookie('csrfToken_j'),
                     async function(result){
                         $.bootstrapLoading.end();

+ 1 - 0
app/public/report/js/rpt_preview_common.js

@@ -57,6 +57,7 @@ async function printPageLoading() {
         let url = '/tender/report_api/getMultiReports';
         if (current_stage_id === -600) url =  '/contract/report_api/getMultiReports';
         if (current_stage_id === -700) url =  `/tender/${params.tid}/phase/report_api/getMultiReports`;
+        if ([-800, -801, -802, -803].includes(current_stage_id)) url =  `/sp/${params.id}/cost/tender/${params.tid}/report_api/getMultiReports`;
         // 
         CommonAjax.postXsrfEx(url, params, 60000, true, getCookie('csrfToken_j'),
             async function(result){

+ 5 - 0
app/public/report/js/rpt_print.js

@@ -22,6 +22,11 @@ let rptPrintHelper = {
                 params.tid = params.tender_id;
                 params.phase_pay_id = BUSINESS_ID;
             }
+            if ([-800, -801, -802, -803].includes(STAGE_ID)) {
+                params.tid = params.tender_id;
+                params.id = PROJECT_ID;
+                params.cost_stage_id = BGL_OBJ.BUSINESS_ID;
+            }
             let chkNodes = zTreeOprObj.treeObj.getCheckedNodes(true);
             if (chkNodes.length > 0) {
                 delete params.orientation; // 打印时有勾选的话,不需要提供方向

+ 9 - 4
app/public/report/js/rpt_public.js

@@ -1,5 +1,13 @@
 const PUB_STAMP_SIZE_WIDTH = 5 * 96 / 2.54;   // 公章大小:宽度(5 CM)
 const PUB_STAMP_SIZE_HEIGHT = 5 * 96 / 2.54;  // 公章大小:高度(5 CM)
+const BIZ_TYPE_MAP = {
+    stage: 1, // 计量期
+    change_prepay: 10, // 预付款
+    change_material_adjustment: 30, // 材差
+    cost_ledger: 400,
+    cost_book: 401, 
+    cost_analysis: 402,
+};
 
 function getScreenDPI() {
     if (SCREEN_DPI.length === 0) {
@@ -365,10 +373,7 @@ function filterReportsByType(allCommonTreeNodes, allIndiTreeNodes, current_biz_t
     }
     const newCommonTreeNodes = JSON.parse(JSON.stringify(allCommonTreeNodes));
     const newCustomTreeNodes = JSON.parse(JSON.stringify(allIndiTreeNodes));
-    let bizType = 1;
-    if (current_biz_type === 'stage') bizType = 1; // 计量期
-    if (current_biz_type === 'change_prepay') bizType = 10; // 预付款
-    if (current_biz_type === 'change_material_adjustment') bizType = 30; // 材差
+    const bizType = BIZ_TYPE_MAP[current_biz_type] || 1
     _filterBySourceType(newCommonTreeNodes, bizType);
     _filterBySourceType(newCustomTreeNodes, bizType);
     topTreeNodes[0].items = [];

+ 2 - 0
app/router.js

@@ -566,6 +566,8 @@ module.exports = app => {
     app.get('/sp/:id/cost/tender/:tid/ledger', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'costController.ledger');
     app.get('/sp/:id/cost/tender/:tid/book', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'costController.book');
     app.get('/sp/:id/cost/tender/:tid/analysis', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'costController.analysis');
+    app.post('/sp/:id/cost/tender/:tid/report_api/getReport', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'reportController.getReport');
+    app.post('/sp/:id/cost/tender/:tid/report_api/getMultiReports', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'reportController.getMultiReportsEx');
     app.post('/sp/:id/cost/tender/:tid/addStage', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'costController.addStage');
     app.post('/sp/:id/cost/tender/:tid/delStage', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'costController.delStage');
     app.post('/sp/:id/cost/tender/:tid/:stype/auditors', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, 'costController.loadAuditors');

+ 5 - 14
app/service/rpt_tree_node.js

@@ -31,7 +31,7 @@ module.exports = app => {
                 value: typeArr,
                 operate: 'in',
             });
-            this.sqlBuilder.columns = ['id', 'name', 'rpt_type', 'pid', 'items', 'last_update_time'];
+            this.sqlBuilder.columns = ['id', 'name', 'rpt_type', 'pid', 'items', 'last_update_time', 'source_type'];
             const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
 
             const list = await this.db.query(sql, sqlParam);
@@ -49,7 +49,7 @@ module.exports = app => {
                 operate: '=',
             });
 
-            this.sqlBuilder.columns = ['id', 'name', 'rpt_type', 'pid', 'items', 'last_update_time'];
+            this.sqlBuilder.columns = ['id', 'name', 'rpt_type', 'pid', 'items', 'last_update_time', 'source_type'];
             const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
 
             const list = await this.db.query(sql, sqlParam);
@@ -62,7 +62,7 @@ module.exports = app => {
                 value: id,
                 operate: '=',
             });
-            this.sqlBuilder.columns = ['id', 'name', 'rpt_type', 'pid', 'items', 'last_update_time'];
+            this.sqlBuilder.columns = ['id', 'name', 'rpt_type', 'pid', 'items', 'last_update_time', 'source_type'];
             const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
 
             const list = await this.db.query(sql, sqlParam);
@@ -88,7 +88,7 @@ module.exports = app => {
                     });
                 }
             }
-            this.sqlBuilder.columns = ['id', 'name', 'rpt_type', 'pid', 'items', 'last_update_time'];
+            this.sqlBuilder.columns = ['id', 'name', 'rpt_type', 'pid', 'items', 'last_update_time', 'source_type'];
             const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
 
             const list = await this.db.query(sql, sqlParam);
@@ -96,16 +96,7 @@ module.exports = app => {
         }
 
         async getAllNodes(prjIdArr) {
-            this.initSqlBuilder();
-            this.sqlBuilder.setAndWhere('pid', {
-                value: prjIdArr,
-                operate: 'in',
-            });
-            this.sqlBuilder.columns = ['id', 'name', 'rpt_type', 'pid', 'items', 'last_update_time', 'source_type'];
-            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
-
-            const list = await this.db.query(sql, sqlParam);
-            return list;
+            return await this.getNodesBySourceType(prjIdArr);
         }
 
         async createNode(prjId, name) {

+ 145 - 2
app/view/report/index.ejs

@@ -147,6 +147,26 @@
                     <a href="/tender/<%- tender_id %>/report/format/setup" class=" btn btn-light btn-sm  text-primary">设置</a>
                 </div>
                 <% } %>
+                <% if ([-800, -801, -802, -803].includes(stg_id)) { %>
+                <div class="d-inline-block">
+                    <div class="dropdown">
+                        <button class="btn btn-sm btn-light dropdown-toggle text-primary" type="button" id="allCostBizDropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                            成本报审
+                        </button>
+                        <div class="dropdown-menu" aria-labelledby="dropdownMenuButton" id="cost-select-item">
+                            <a class="dropdown-item" href="javascript:void(0);" data-type="cost_ledger" style="display: none">成本报审</a>
+                            <a class="dropdown-item" href="javascript:void(0);" data-type="cost_book">财务账面</a>
+                            <a class="dropdown-item" href="javascript:void(0);" data-type="cost_analysis">成本分析</a>
+                        </div>
+                    </div>
+                </div>
+                <div class="d-inline-block">
+                    <div class="dropdown" id="divSelectableCostStages">
+                        <button class="btn btn-sm btn-light dropdown-toggle text-primary" type="button" id="btnCurrentCostStage" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
+                        <div class="dropdown-menu" aria-labelledby="divSelectableCostStages" id="optionSelectableCostStages"></div>
+                    </div>
+                </div>
+                <% } %>
             </div>
             <div>
             </div>
@@ -195,7 +215,7 @@
                                     导出报表
                                 </div>
                             </div>
-                            <% if(![-600, -700].includes(stg_id)) { %>
+                            <% if(![-600, -700, -800, -801, -802].includes(stg_id)) { %>
                             <div class="panel" id="archiveTopDiv" <% if (pageShow === null || parseInt(pageShow.showArchive) === 0 || isNaN(parseInt(pageShow.showArchive))) { %> style="display:none" <% } %>>
                                 <div class="panel-body">
                                     <div class="btn-group" role="group">
@@ -439,6 +459,50 @@
         advancePayClick(this);
     });
 
+    $('#cost-select-item a').on('click', function () {
+        $('#cost-select-item a').show();
+        $(this).hide();
+        $('#cost-select-item').siblings('button').text($(this).text());
+        const type = $(this).data('type');
+        CURRENT_SELECTED_BIZ_TYPE = type;
+        switch (type) {
+            case 'cost_ledger':
+                current_stage_id = -800;
+                current_stage_times = BGL_OBJ.ledge[0].audit_times;
+                SOURCE_TYPE = 400;
+                BGL_OBJ.source_type = 400;
+                if (BGL_OBJ.ledge.length > 0) {
+                    BGL_OBJ.BUSINESS_ID = BGL_OBJ.ledge[0].id;
+                    BGL_OBJ.status = BGL_OBJ.ledge[0].audit_status;
+                }
+                break;
+            case 'cost_book':
+                current_stage_id = -801;
+                current_stage_times = BGL_OBJ.book[0].audit_times;
+                SOURCE_TYPE = 401;
+                BGL_OBJ.source_type = 401;
+                if (BGL_OBJ.book.length > 0) { 
+                    BGL_OBJ.BUSINESS_ID = BGL_OBJ.book[0].id;
+                    BGL_OBJ.status = BGL_OBJ.book[0].audit_status;
+                }
+                break;
+            case 'cost_analysis':
+                current_stage_id = -802;
+                current_stage_times = BGL_OBJ.analysis[0].audit_times;
+                SOURCE_TYPE = 402;
+                BGL_OBJ.source_type = 402;
+                if (BGL_OBJ.analysis.length > 0) {
+                    BGL_OBJ.BUSINESS_ID = BGL_OBJ.analysis[0].id;
+                    BGL_OBJ.status = BGL_OBJ.analysis[0].audit_status;
+                }
+                break;
+        }
+        rptArchiveObj.toggleBtn(true);
+        filterReportsByType(ALL_COMMON_TREE_NODES, ALL_INDIVI_TREE_NODES, CURRENT_SELECTED_BIZ_TYPE, TOP_TREE_NODES, CUST_TREE_NODES);
+        zTreeOprObj.getReportTemplateTree();
+        buildCostStageSelection();
+    });
+
     $('#biz-select-item a').on('click', function () {
         $('#biz-select-item a').show();
         $(this).hide();
@@ -465,6 +529,7 @@
             // 还有归档按钮处理
             // current_stage_id
             rptArchiveObj.toggleBtn(true);
+            buildMaterialSelection();
             filterReportsByType(ALL_COMMON_TREE_NODES, ALL_INDIVI_TREE_NODES, CURRENT_SELECTED_BIZ_TYPE, TOP_TREE_NODES, CUST_TREE_NODES);
             zTreeOprObj.getReportTemplateTree();
         } else if (type === 'change_prepay') {
@@ -738,6 +803,9 @@
     <% if (false || ![-100, -150, -200, -300, -301, -302, -303, -600, -700, -800, -801, -802, -803].includes(stg_id)) { %>
     buildStageSelection();
     <% } %>
+    <% if ([-800, -801, -802, -803].includes(stg_id)) { %>
+    buildCostStageSelection();
+    <% } %>
     setupSignature();
 
     for (let item of TOP_TREE_NODES) {
@@ -821,6 +889,42 @@
         }
     }
 
+    function buildCostStageSelection() {
+        $("#optionSelectableCostStages").empty();
+        const commonOperation = (costObjs) => {
+            if (costObjs.length === 0) {
+                $("#divSelectableCostStages")[0].style.display = 'none';
+            } else {
+                $("#divSelectableCostStages")[0].style.display = '';
+                $("#optionSelectableCostStages")[0].style.display = '';
+                const obj = costObjs.find(costObj => costObj.id === BGL_OBJ.BUSINESS_ID);
+                const stgOrder = obj ? obj.stage_order : costObjs.length;
+                $("#btnCurrentCostStage")[0].innerText = `第${stgOrder}期`;
+                $("#optionSelectableCostStages").empty();
+                for (let i = 0; i < costObjs.length; i++) {
+                    if (costObjs[i].stage_order !== stgOrder) {
+                        const str = `<a class="dropdown-item" style="cursor:pointer" onclick="changeCurrentCostStage(this)" stg_id="${costObjs[i].id}" stg_order="${costObjs[i].stage_order}">第${costObjs[i].stage_order}期</a>`;
+                        $("#optionSelectableCostStages").append(str);
+                    }
+                }
+            }
+        };
+        switch (SOURCE_TYPE) {
+            case 400:
+                commonOperation(BGL_OBJ.allStages.ledge);
+                break;
+            case 401:
+                commonOperation(BGL_OBJ.allStages.book);
+                break;
+            case 402:
+                commonOperation(BGL_OBJ.allStages.analysis);
+                break;
+            default:
+                $("#divSelectableCostStages")[0].style.display = 'none';
+                break;
+        }
+    }
+
     function buildStageSelection() {
         if (STAGE_LIST.length === 0) {
             $("#optionSelectableStages")[0].style.display = 'none';
@@ -949,6 +1053,39 @@
         getReportArchive();
     }
 
+    function changeCurrentCostStage(ele) {
+        const costStgId = ele.attributes.stg_id.value;
+        const changeCostStage = (stgObjs) => {
+            for (const stg of stgObjs) {
+                if (stg.id === costStgId) {
+                    BGL_OBJ.BUSINESS_ID = stg.id;
+                    BUSINESS_ID = stg.id;
+                    BGL_OBJ.status = stg.audit_status;
+                    current_stage_times = stg.audit_times;
+                    current_stage_status = stg.audit_status;
+                    break;
+                }
+            }
+        };
+        switch (BGL_OBJ.source_type) {
+            case 400:
+                changeCostStage(BGL_OBJ.allStages.ledge);
+                break;
+            case 401:
+                changeCostStage(BGL_OBJ.allStages.book);
+                break;
+            case 402:
+                changeCostStage(BGL_OBJ.allStages.analysis);
+                break;
+        }
+
+        buildCostStageSelection();
+        setupSignature();
+        zTreeOprObj.refreshNodes();
+        zTreeOprObj.countChkedRptTpl();
+        selectPreRptTpl();
+    }
+
     function changeCurrentStage(ele) {
         // alert('you are selecting: ' + ele.innerText);
         current_stage_order = parseInt(ele.attributes.stg_order.value);
@@ -973,6 +1110,8 @@
             params.bizId = current_advance_id;
         } else if (current_stage_id === -500) {
             params.bizId = current_material_id;
+        } else if (current_stage_id === -800) {
+            params.bizId = BGL_OBJ.BUSINESS_ID;
         }
         $.bootstrapLoading.start();
         CommonAjax.postXsrfEx("/tender/report_api/getReportArchive", params, 10000, true, getCookie('csrfToken_j'),
@@ -980,7 +1119,11 @@
                 $.bootstrapLoading.end();
                 ARCHIVE_LIST = result.data;
                 LAST_AUDITOR = result.lastAuditor;
-                buildStageSelection();
+                if (current_stage_id === -800) {
+                    buildCostStageSelection();
+                } else {
+                    buildStageSelection();
+                }
                 setupSignature();
                 zTreeOprObj.refreshNodes();
                 zTreeOprObj.countChkedRptTpl();