Forráskód Böngészése

多标段汇总,新增2种汇总模式

MaiXinRong 4 éve
szülő
commit
5ee8c0388f

+ 1 - 0
app/public/js/shares/tenders2tree.js

@@ -85,6 +85,7 @@ const Tender2Tree = (function () {
                 tid: t.id,
                 name: t.name,
                 phase: t.lastStage ? '第' + t.lastStage.order + '期' : '台账',
+                stageCount: t.lastStage ? t.lastStage.order : 0,
             };
             if (ledgerAuditConst && stageAuditConst) {
                 node.status = t.lastStage ? stageAuditConst.statusString[t.lastStage.status] : ledgerAuditConst.statusString[t.ledger_status];

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

@@ -1825,7 +1825,7 @@ $(document).ready(() => {
         if (result.cooperation) {
             stageTree.loadPwd(result.cooperation, 'bills-p-' + userID + '-' + window.location.pathname.split('/')[2]);
             $('#cooperationCount').html(stageTree.pwd.length || '');
-            $('#cooperationCount').parent().show();
+            if (stageTree.pwd.length > 0) $('#cooperationCount').parent().show();
             reloadCooperationHtml();
         }
         // 加载部位明细

+ 63 - 13
app/public/report/js/rpt_custom.js

@@ -43,11 +43,28 @@ const rptCustomObj = (function () {
         headColWidth: []
     };
     const gatherSelectSpreadObj = {
+        _getStageSelectHtml: function (valid) {
+            const html = [];
+            for (let i = 1; i <= valid; i++) {
+                html.push(`<option value="${i}">第${i}期</option>`);
+            }
+            return html.join('');
+        },
+        _rebuildStageSelect: function () {
+            if (gsObj.setting.type === 'stage') {
+                const validStage = _.min(_.map(gsObj.grArray, 'stageCount'));
+                $('#gather-stage').html(this._getStageSelectHtml(validStage));
+            } else if (gsObj.setting.type === 'stage-zone') {
+                const validStage = _.max(_.map(gsObj.grArray, 'stageCount'));
+                $('#gather-stage-begin').html(this._getStageSelectHtml(validStage));
+                $('#gather-stage-end').html(this._getStageSelectHtml(validStage));
+            }
+        },
         _addTender: function (tender) {
             const gr = gsObj.grArray.find(function (x) {
                 return x.tid === tender.tid;
             });
-            const t = {tid: tender.tid, name: tender.name}
+            const t = {tid: tender.tid, name: tender.name, stageCount: tender.stageCount};
             if (!gr) gsObj.grArray.push(t);
             return t;
         },
@@ -59,6 +76,7 @@ const rptCustomObj = (function () {
         },
         reloadResultData: function () {
             SpreadJsObj.reLoadSheetData(gsObj.grSheet);
+            this._rebuildStageSelect();
         },
         gsButtonClicked: function (e, info) {
             if (!info.sheet.zh_setting) return;
@@ -217,26 +235,30 @@ const rptCustomObj = (function () {
         $('#gather-select-title').html(gsObj.setting.title + (rptName ? '-' + rptName : ''));
         initGrSpreadSetting(gsObj.setting);
         SpreadJsObj.initSheet(gsObj.grSheet, grSpreadSetting);
-        if (gsObj.setting.type === 'month') {
-            $('#gather-by-month').show();
-            $('#gather-by-zone').hide();
-        } else if (gsObj.setting.type === 'zone') {
-            $('#gather-by-month').hide();
-            $('#gather-by-zone').show();
-        } else {
-            $('#gather-by-month').hide();
-            $('#gather-by-zone').hide();
-        }
-        SpreadJsObj.loadSheetData(gsObj.grSheet, SpreadJsObj.DataType.Data, gsObj.grArray);
+
         // 初始化选择结果
+        SpreadJsObj.loadSheetData(gsObj.grSheet, SpreadJsObj.DataType.Data, gsObj.grArray);
+        gatherSelectSpreadObj.initSelectTenders(gsSelect ? gsSelect.tenders : []);
+
+        $('[name=gather-type]').hide();
+        if (gsObj.setting.type === 'month') $('#gather-by-month').show();
+        if (gsObj.setting.type === 'zone') $('#gather-by-zone').show();
+        if (gsObj.setting.type === 'stage') $('#gather-by-stage').show();
+        if (gsObj.setting.type === 'stage-zone') $('#gather-by-stage-zone').show();
+
         if (gsSelect) {
             if (gsSelect.zone) {
                 $('#gather-zone').val(gsSelect.zone ? gsSelect.zone : '');
             } else if (gsSelect.month) {
                 $('#gather-month').val(gsSelect.month ? gsSelect.month: '');
+            } else if (gsSelect.stage) {
+                $('#gather-stage').val(gsSelect.stage || '');
+            } else if (gsSelect.stage_zone) {
+                const [stageBegin, stageEnd] = gsSelect.stage_zone ? gsSelect.stage_zone.split(':') : ['', ''];
+                $('#gather-stage-begin').val(stageBegin);
+                $('#gather-stage-end').val(stageEnd);
             }
         }
-        gatherSelectSpreadObj.initSelectTenders(gsSelect ? gsSelect.tenders : []);
 
         // 初始化
         $("#gather-select").modal('show');
@@ -423,6 +445,34 @@ const rptCustomObj = (function () {
                 hintObj.html('请选择 完整汇总周期').show();
                 return;
             }
+        } else if (gsObj.setting.type === 'stage') {
+            data[sGatherSelect].stage = _.toInteger($('#gather-stage').val()) || 0;
+            const validStage = _.min(_.map(gsObj.grArray, 'stageCount'));
+            if (!data[sGatherSelect].stage) {
+                hintObj.html('请选择 汇总期').show();
+                return;
+            }
+            if (data[sGatherSelect].stage > validStage) {
+                hintObj.html('选择的期无效,请重新选择').show();
+                return;
+            }
+        } else if (gsObj.setting.type === 'stage-zone') {
+            const stageBegin = _.toInteger($('#gather-stage-begin').val()) || 0;
+            const stageEnd = _.toInteger($('#gather-stage-end').val()) || 0;
+            const validStage = _.max(_.map(gsObj.grArray, 'stageCount'));
+            if (!stageBegin || !stageEnd) {
+                hintObj.html('请选择 汇总开始期与结束期').show();
+                return;
+            }
+            if (stageEnd <= stageBegin) {
+                hintObj.html('结束期应大于开始期').show();
+                return;
+            }
+            if (stageEnd > validStage) {
+                hintObj.html('选择的期无效,请重新选择').show();
+                return;
+            }
+            data[sGatherSelect].stage_zone = stageBegin + ':' + stageEnd;
         }
         hintObj.hide();
         if (resolve) {

+ 157 - 82
app/service/rpt_gather_memory.js

@@ -210,6 +210,35 @@ module.exports = app => {
             return '';
         }
 
+        async _getTimeZoneStages(tender, zone) {
+            const times = zone.split(' - ');
+            if (times.length !== 2) throw '选择的汇总周期无效';
+            const beginTime = moment(times[0], 'YYYY-MM');
+            const endTime = moment(times[1], 'YYYY-MM');
+
+            const stages = await this._getValidStages(tender.id), validStages = [];
+            for (const stage of stages) {
+                const sTime = moment(stage.s_time, 'YYYY-MM');
+                if (sTime.isBetween(beginTime, endTime, null, '[]')) {
+                    validStages.push(stage);
+                }
+            }
+            return validStages;
+        }
+
+        async _getOrderZoneStages (tender, zone) {
+            let [iBegin, iEnd] = zone.split(':');
+            iBegin = this.ctx.helper._.toInteger(iBegin) || 0;
+            iEnd = this.ctx.helper._.toInteger(iEnd) || 0;
+            const stages = await this._getValidStages(tender.id), validStages = [];
+            for (const stage of stages) {
+                if (stage.order < iBegin || stage.order > iEnd) continue;
+
+                validStages.push(stage);
+            }
+            return validStages;
+        }
+
         /**
          * 台账数据
          */
@@ -278,15 +307,10 @@ module.exports = app => {
 
         }
 
-        async _gatherMonthData(sTender, completeData, month, hasPre) {
-            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
-            const stages = await this._getValidStages(tender.id);
-            const stage = this.ctx.helper._.find(stages, {s_time: month});
-            await this._gatherStageData(completeData, tender, stage, hasPre);
-        }
-
-        async _gatherZoneData(sTender, completeData, zone) {
+        async _gatherStagesData(completeData, tender, stages) {
             const helper = this.ctx.helper;
+            completeData.id = tender.id;
+            completeData.name = tender.name;
             /**
              * 汇总并合并 相关数据
              * @param {Array} index - 主数据
@@ -310,7 +334,6 @@ module.exports = app => {
                     loadFields(r.data, r.fields, r.prefix, r.relaId);
                 }
             };
-
             const billsTree = new Ledger.billsTree(this.ctx, {
                 id: 'ledger_id',
                 pid: 'ledger_pid',
@@ -327,9 +350,6 @@ module.exports = app => {
                     node.gather_tp = helper.add(node.contract_tp, node.qc_tp);
                 }
             });
-            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
-            completeData.id = tender.id;
-            completeData.name = tender.name;
             const billsData = await this.ctx.service.ledger.getData(tender.id);
 
             const dgnData = await this.ctx.service.stageBillsDgn.getDgnData(tender.id);
@@ -343,30 +363,22 @@ module.exports = app => {
                 billsIndexData[indexPre + bd.id] = bd;
             }
 
-            const times = zone.split(' - ');
-            if (times.length !== 2) throw '选择的汇总周期无效';
-            const beginTime = moment(times[0], 'YYYY-MM');
-            const endTime = moment(times[1], 'YYYY-MM');
-
-            const stages = await this._getValidStages(tender.id);
             for (const stage of stages) {
-                const sTime = moment(stage.s_time, 'YYYY-MM');
-                if (sTime.isBetween(beginTime, endTime, null, '[]')) {
-                    await this.ctx.service.stage.doCheckStage(stage);
-                    if (stage.readOnly) {
-                        const curStage = await this.ctx.service.stageBills.getAuditorStageData(tender.id,
-                            stage.id, stage.curTimes, stage.curOrder);
-                        sumAssignRelaData(billsIndexData, [
-                            {data: curStage, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: '', relaId: 'lid'}
-                        ]);
-                    } else {
-                        const curStage = await this.ctx.service.stageBills.getLastestStageData(tender.id, stage.id);
-                        sumAssignRelaData(billsIndexData, [
-                            {data: curStage, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: '', relaId: 'lid'}
-                        ]);
-                    }
+                await this.ctx.service.stage.doCheckStage(stage);
+                if (stage.readOnly) {
+                    const curStage = await this.ctx.service.stageBills.getAuditorStageData(tender.id,
+                        stage.id, stage.curTimes, stage.curOrder);
+                    sumAssignRelaData(billsIndexData, [
+                        {data: curStage, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: '', relaId: 'lid'}
+                    ]);
+                } else {
+                    const curStage = await this.ctx.service.stageBills.getLastestStageData(tender.id, stage.id);
+                    sumAssignRelaData(billsIndexData, [
+                        {data: curStage, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: '', relaId: 'lid'}
+                    ]);
                 }
             }
+
             billsTree.loadDatas(billsData);
             billsTree.calculateAll();
             this.resultTree.loadGatherTree(billsTree, function (gatherNode, sourceNode) {
@@ -374,6 +386,32 @@ module.exports = app => {
             });
         }
 
+        async _gatherMonthData(sTender, completeData, month, hasPre) {
+            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
+            const stages = await this._getValidStages(tender.id);
+            const stage = this.ctx.helper._.find(stages, {s_time: month});
+            await this._gatherStageData(completeData, tender, stage, hasPre);
+        }
+
+        async _gatherIndexData(sTender, completeData, index, hasPre) {
+            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
+            const stages = await this._getValidStages(tender.id);
+            const stage = this.ctx.helper._.find(stages, {order: index});
+            await this._gatherStageData(completeData, tender, stage, hasPre);
+        }
+
+        async _gatherZoneData(sTender, completeData, zone) {
+            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
+            const stages = await this._getTimeZoneStages(tender, zone);
+            await this._gatherStagesData(completeData, tender, stages);
+        }
+
+        async _gatherIndexZoneData(sTender, completeData, stageZone) {
+            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
+            const stages = await this._getOrderZoneStages(tender, stageZone);
+            await this._gatherStagesData(completeData, tender, stages);
+        }
+
         async _gatherFinalData(sTender, completeData, hasPre) {
             const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
             const stages = await this._getValidStages(tender.id);
@@ -458,6 +496,12 @@ module.exports = app => {
                         case 'ledger':
                             await this._gatherLedgerData(tender, completeData);
                             break;
+                        case 'stage':
+                            await this._gatherIndexData(tender, completeData, gsCustom.stage, gsSetting.hasPre);
+                            break;
+                        case 'stage-zone':
+                            await this._gatherIndexZoneData(tender, completeData, gsCustom.stage_zone);
+                            break;
                     }
                     commonIndex++;
                 } else {
@@ -522,6 +566,20 @@ module.exports = app => {
             }
         }
 
+        async _getStagesTenderInfo(stages, info) {
+            const helper = this.ctx.helper;
+            for (const stage of stages) {
+                await this.ctx.service.stage.doCheckStage(stage);
+                await this.ctx.service.stage.checkStageGatherData(stage);
+
+                info.contract_tp = helper.add(info.contract_tp, stage.contract_tp);
+                info.qc_tp = helper.add(info.qc_tp, stage.qc_tp);
+
+                info.yf_tp = helper.add(info.yf_tp, stage.yf_tp);
+            }
+            info.gather_tp = helper.add(info.contract_tp, info.qc_tp);
+        }
+
         async _gatherMonthTenderInfo(sTender, index, month, hasPre) {
             const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
             const info = await this._getBaseTenderInfo(tender);
@@ -531,31 +589,28 @@ module.exports = app => {
             this.resultTenderInfo.push(info);
         }
 
-        async _gatherZoneTenderInfo(sTender, index, zone) {
-            const helper = this.ctx.helper;
+        async _gatherOrderTenderInfo(sTender, index, order, hasPre) {
             const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
             const info = await this._getBaseTenderInfo(tender);
+            const stages = await this._getValidStages(tender.id);
+            const stage = this.ctx.helper._.find(stages, {order: order});
+            await this._getStageTenderInfo(stage, info);
+            this.resultTenderInfo.push(info);
+        }
 
-            const times = zone.split(' - ');
-            if (times.length !== 2) throw '选择的汇总周期无效';
-            const beginTime = moment(times[0], 'YYYY-MM');
-            const endTime = moment(times[1], 'YYYY-MM');
-
-            const stages = await this._getValidStages(tender.id, true);
-            for (const stage of stages) {
-                const sTime = moment(stage.s_time, 'YYYY-MM');
-                if (sTime.isBetween(beginTime, endTime, null, '[]')) {
-                    await this.ctx.service.stage.doCheckStage(stage);
-                    await this.ctx.service.stage.checkStageGatherData(stage);
-
-                    info.contract_tp = helper.add(info.contract_tp, stage.contract_tp);
-                    info.qc_tp = helper.add(info.qc_tp, stage.qc_tp);
-
-                    info.yf_tp = helper.add(info.yf_tp, stage.yf_tp);
-                }
-            }
-            info.gather_tp = helper.add(info.contract_tp, info.qc_tp);
+        async _gatherZoneTenderInfo(sTender, index, zone) {
+            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
+            const info = await this._getBaseTenderInfo(tender);
+            const stages = await this._getTimeZoneStages(tender, zone);
+            await this._getStagesTenderInfo(stages, info);
+            this.resultTenderInfo.push(info);
+        }
 
+        async _gatherOrderZoneTenderInfo(sTender, index, stageZone) {
+            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
+            const info = await this._getBaseTenderInfo(tender);
+            const stages = await this._getOrderZoneStages(tender, stageZone);
+            await this._getStagesTenderInfo(stages, info);
             this.resultTenderInfo.push(info);
         }
 
@@ -615,6 +670,12 @@ module.exports = app => {
                         case 'ledger':
                             await this._gatherLedgerTenderInfo(tender, commonIndex);
                             break;
+                        case 'stage':
+                            await this._gatherOrderTenderInfo(tender, commonIndex, gsCustom.stage, gsSetting.hasPre);
+                            break;
+                        case 'stage-zone':
+                            await this._gatherOrderZoneTenderInfo(tender, commonIndex, gsCustom.stage_zone);
+                            break;
                     }
                     commonIndex++;
                 } else {
@@ -685,6 +746,29 @@ module.exports = app => {
             }
         }
 
+        async _gatherStagesPay(completeData, tender, stages) {
+            const helper = this.ctx.helper;
+            completeData.id = tender.id;
+            completeData.name = tender.name;
+
+            for (const stage of stages) {
+                await this.ctx.service.stage.doCheckStage(stage);
+
+                const dealPay = await this.ctx.service.stagePay.getStagePays(stage);
+                await this._checkStagePayCalc(tender, stage, dealPay);
+                for (const dp of dealPay) {
+                    dp.end_tp = helper.add(dp.pre_tp, dp.tp);
+                    this._gatherPayRecord(dp, function (gatherData, sourceData) {
+                        gatherData[completeData.prefix + 'id'] = tender.id;
+                        gatherData[completeData.prefix + 'name'] = tender.name;
+
+                        gatherData[completeData.prefix + 'tp'] = helper.add(gatherData[completeData.prefix + 'tp'], sourceData.tp);
+                        gatherData['s_' + 'tp'] = helper.add(gatherData['s_' + 'tp'], sourceData.tp);
+                    });
+                }
+            }
+        }
+
         async _gatherMonthStagePay(sTender, completeData, month, hasPre) {
             const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
             const stages = await this._getValidStages(tender.id);
@@ -692,38 +776,23 @@ module.exports = app => {
             await this._gatherStagePay(completeData, tender, stage, hasPre);
         }
 
-        async _gatherZoneStagePay(sTender, completeData, zone) {
-            const helper = this.ctx.helper;
-
+        async _gatherOrderStagePay(sTender, completeData, order, hasPre) {
             const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
-            completeData.id = tender.id;
-            completeData.name = tender.name;
             const stages = await this._getValidStages(tender.id);
+            const stage = this.ctx.helper._.find(stages, {order: order});
+            await this._gatherStagePay(completeData, tender, stage, hasPre);
+        }
 
-            const times = zone.split(' - ');
-            if (times.length !== 2) throw '选择的汇总周期无效';
-            const beginTime = moment(times[0], 'YYYY-MM');
-            const endTime = moment(times[1], 'YYYY-MM');
+        async _gatherZoneStagePay(sTender, completeData, zone) {
+            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
+            const stages = await this._getTimeZoneStages(tender, zone);
+            await this._gatherStagesPay(completeData, tender, stages);
+        }
 
-            for (const stage of stages) {
-                const sTime = moment(stage.s_time, 'YYYY-MM');
-                if (sTime.isBetween(beginTime, endTime, null, '[]')) {
-                    await this.ctx.service.stage.doCheckStage(stage);
-
-                    const dealPay = await this.ctx.service.stagePay.getStagePays(stage);
-                    await this._checkStagePayCalc(tender, stage, dealPay);
-                    for (const dp of dealPay) {
-                        dp.end_tp = helper.add(dp.pre_tp, dp.tp);
-                        this._gatherPayRecord(dp, function (gatherData, sourceData) {
-                            gatherData[completeData.prefix + 'id'] = tender.id;
-                            gatherData[completeData.prefix + 'name'] = tender.name;
-
-                            gatherData[completeData.prefix + 'tp'] = helper.add(gatherData[completeData.prefix + 'tp'], sourceData.tp);
-                            gatherData['s_' + 'tp'] = helper.add(gatherData['s_' + 'tp'], sourceData.tp);
-                        });
-                    }
-                }
-            }
+        async _gatherOrderZoneStagePay(sTender, completeData, stageZone) {
+            const tender = await this.ctx.service.tender.getCheckTender(sTender.tid);
+            const stages = await this._getOrderZoneStages(tender, stageZone)
+            await this._gatherStagesPay(completeData, tender, stages);
         }
 
         async _gatherFinalStagePay(sTender, completeData, hasPre) {
@@ -766,6 +835,12 @@ module.exports = app => {
                         case 'checked-final':
                             await this._gatherCheckedFinalStagePay(tender, completeData, gsSetting.hasPre);
                             break;
+                        case 'stage':
+                            await this._gatherOrderStagePay(tender, completeData, gsCustom.stage, gsSetting.hasPre);
+                            break;
+                        case 'stage-zone':
+                            await this._gatherOrderZoneStagePay(tender, completeData, gsCustom.stage_zone);
+                            break;
                     }
                     commonIndex++;
                 }

+ 28 - 2
app/view/report/rpt_all_popup.ejs

@@ -357,7 +357,7 @@
                         <h5>已选标段 </h5>
                         <div class="modal-height-300" id="gather-result-spread">
                         </div>
-                        <div class="mt-1" id="gather-by-month" style="width: 60%">
+                        <div class="mt-1" id="gather-by-month" style="width: 60%" name="gather-type">
                             <div class="input-group input-group-sm">
                                 <div class="input-group-prepend">
                                     <span class="input-group-text">汇总年月</span>
@@ -365,7 +365,7 @@
                                 <input id="gather-month" class="datepicker-here form-control form-control-sm" auto-close="true" autocomplete="off" placeholder="点击选择年月" data-view="months" data-min-view="months" data-date-format="yyyy-MM" data-language="zh" type="text" autocomplete="off">
                             </div>
                         </div>
-                        <div id="gather-by-zone">
+                        <div id="gather-by-zone" name="gather-type">
                             <div class="input-group input-group-sm">
                                 <div class="input-group-prepend">
                                     <span class="input-group-text">汇总周期</span>
@@ -373,6 +373,32 @@
                                 <input id="gather-zone" class="datepicker-here form-control mt-0" placeholder="点击选择周期" data-range="true" data-multiple-dates-separator=" - "  data-min-view="months" data-view="months" data-date-format="yyyy-MM" data-language="zh" type="text" autocomplete="off">
                             </div>
                         </div>
+                        <div id="gather-by-stage" name="gather-type">
+                            <div class="input-group input-group-sm">
+                                <div class="input-group-prepend">
+                                    <span class="input-group-text">选择期</span>
+                                </div>
+                                <select class="form-control" id="gather-stage">
+                                    <option>第1期</option>
+                                </select>
+                            </div>
+                        </div>
+                        <div id="gather-by-stage-zone" name="gather-type">
+                            <div class="input-group input-group-sm">
+                                <div class="input-group-prepend">
+                                    <span class="input-group-text">汇总</span>
+                                </div>
+                                <select class="form-control" id="gather-stage-begin">
+                                    <option>第1期</option>
+                                </select>
+                                <div class="input-group-prepend">
+                                    <span class="input-group-text">至</span>
+                                </div>
+                                <select class="form-control" id="gather-stage-end">
+                                    <option>第5期</option>
+                                </select>
+                            </div>
+                        </div>
                     </div>
                     <div class="text-danger text-center ml-3" id="gather-hint">我是提示呀</div>
                 </div>