MaiXinRong 3 місяців тому
батько
коміт
748ecd183d

+ 151 - 9
app/controller/spss_controller.js

@@ -161,6 +161,14 @@ module.exports = app => {
             info.yf_tp = this.ctx.helper.add(stage.yf_tp, info.yf_tp);
             info.sf_tp = this.ctx.helper.add(stage.sf_tp, info.sf_tp);
         }
+        async _loadFakeStageTpData(info, tender, stage) {
+            if (!stage) return;
+            if (!stage.readOnly) await this.ctx.service.stage.checkStageGatherData(stage, this.ctx.session.sessionUser.is_admin);
+            info.pre_contract_tp = this.ctx.helper.sum([stage.contract_tp, stage.pre_contract_tp, stage.contract_pc_tp]);
+            info.pre_qc_tp = this.ctx.helper.sum([stage.qc_tp, stage.pre_qc_tp, stage.qc_pc_tp]);
+            info.pre_yf_tp = this.ctx.helper.add(stage.yf_tp, stage.pre_yf_tp);
+            info.pre_sf_tp = this.ctx.helper.add(stage.sf_tp, stage.pre_sf_tp);
+        }
         async _loadStagesTpData(info, tender, stages, preStage, endStage) {
             if (preStage) {
                 info.pre_contract_tp = this.ctx.helper.sum([preStage.contract_tp, preStage.pre_contract_tp, preStage.contract_pc_tp]);
@@ -183,7 +191,11 @@ module.exports = app => {
             info.change_tp = tender.change_tp;
             info.progress = tender.progress;
             if (filter.type === 'stage') {
-                await this._loadStageTpData(info, tender, filter.stage);
+                if (filter.stage.__fake) {
+                    await this._loadFakeStageTpData(info, tender, filter.stage);
+                } else {
+                    await this._loadStageTpData(info, tender, filter.stage);
+                }
             } else {
                 await this._loadStagesTpData(info, tender, filter.stages, filter.preStage, filter.endStage);
             }
@@ -243,7 +255,24 @@ module.exports = app => {
                 }
             }
             if (stage) await this.ctx.service.stage.doCheckStage(stage);
-            return { type: 'stage', stage, filter: stage ? stage.s_time : month };
+            return { type: 'stage', stage, filter: stage ? stage.s_time : '' };
+        }
+        async _filterFakeMonth(tender, month, checked) {
+            const stages = await this._getValidStages(tender.id, 'desc', checked);
+            let stage = this.ctx.helper._.find(stages, { s_time: month });
+            if (!stage) {
+                const checkTime = moment(month);
+                for (const s of stages) {
+                    const rela_time = moment(s.s_time);
+                    if (rela_time.isBefore(checkTime)) {
+                        stage = s;
+                        stage.__fake = true;
+                        break;
+                    }
+                }
+            }
+            if (stage) await this.ctx.service.stage.doCheckStage(stage);
+            return { type: 'stage', stage, filter: month };
         }
         async _filterFinal(tender, checked) {
             const stages = await this._getValidStages(tender.id, 'desc', checked);
@@ -311,6 +340,8 @@ module.exports = app => {
                     return await this._filterOrderZone(tender, stageInfo.stage_zone, stageInfo.checked);
                 case 'under-month':
                     return await this._filterUnderMonth(tender, stageInfo.month, stageInfo.checked);
+                case 'fake-month':
+                    return await this._filterFakeMonth(tender, stageInfo.month, stageInfo.checked);
                 default:
                     return;
             }
@@ -348,6 +379,28 @@ module.exports = app => {
             ]);
             return [bills, pos];
         }
+        async _loadFakeStageData(tender, stage) {
+            const bills = await this.ctx.service.ledger.getAllDataByCondition({
+                columns: ['id', 'ledger_id', 'ledger_pid', 'level', 'full_path', 'is_leaf', 'order', 'code', 'b_code', 'name', 'unit', 'unit_price', 'quantity', 'total_price'],
+                where: { tender_id: tender.id },
+            });
+            const pos = await this.ctx.service.pos.getAllDataByCondition({
+                columns: ['id', 'lid', 'name', 'quantity', 'porder'],
+                where: { tid: tender.id },
+            });
+            if (!stage) return [bills, pos];
+
+            const preStage = stage.preCheckedStage ? await this.ctx.service.stageBillsFinal.getFinalData(tender, stage.order) : [];
+            this.ctx.helper.assignRelaData(bills, [
+                { data: preStage, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: 'pre_', relaId: 'lid' },
+            ]);
+
+            const preStagePos = stage.preCheckedStage ? await this.ctx.service.stagePosFinal.getFinalData(tender, stage.preCheckedStage.order) : [];
+            this.ctx.helper.assignRelaData(pos, [
+                { data: preStagePos, fields: ['contract_qty', 'qc_qty'], prefix: 'pre_', relaId: 'pid' },
+            ]);
+            return [bills, pos];
+        }
         async _loadStagesData(tender, stages, preStage, endStage) {
             const indexPre = 'id_', helper = this.ctx.helper;
             const sumAssignRelaData = function (index, rela) {
@@ -419,7 +472,7 @@ module.exports = app => {
         }
         async _loadStageLedgerData(tender, filter) {
             return filter.type === 'stage'
-                ? await this._loadStageData(tender, filter.stage)
+                ? (filter.stage.__fake ? await this._loadFakeStageData(tender, filter.stage) : await this._loadStageData(tender, filter.stage))
                 : await this._loadStagesData(tender, filter.stages, filter.preStage, filter.endStage);
         }
 
@@ -435,13 +488,29 @@ module.exports = app => {
             }
             return dealPay;
         }
+        async _loadFakeStagePayData(tender, stage) {
+            if (!stage) return [];
+
+            const dealPay = await this.ctx.service.stagePay.getStagePays(stage);
+            if (!stage.readOnly) {
+                // 计算 本期金额
+                const PayCalculator = require('../lib/pay_calc');
+                const payCalculator = new PayCalculator(this.ctx, stage, tender.info);
+                await payCalculator.calculateAll(dealPay);
+            }
+            for (const dp of dealPay) {
+                dp.pre_tp = dp.end_tp;
+                dp.tp = 0;
+            }
+            return dealPay;
+        }
         async _loadStagesPayData(tender, stages, preStage, endStage) {
             // todo
             return [];
         }
         async _loadPayData(tender, filter) {
             return filter.type === 'stage'
-                ? await this._loadStagePayData(tender, filter.stage)
+                ? (filter.stage.__fake ? await this._loadFakeStagePayData(tender, filter.stage) : await this._loadStagePayData(tender, filter.stage))
                 : await this._loadStagesPayData(tender, filter.stage, filter.preStage, filter.endStage);
         }
 
@@ -465,13 +534,33 @@ module.exports = app => {
             }
             return data;
         }
+        async _loadFakeStageJgclData(tender, stage) {
+            if (!stage) return [];
+
+            const data = await this.ctx.service.stageJgcl.getStageData(stage);
+            for (const d of data) {
+                d.pre_arrive_qty = d.arrive_qty;
+                d.pre_arrive_tp = d.arrive_tp;
+                d.pre_deduct_qty = d.deduct_qty;
+                d.pre_deduct_tp = d.deduct_tp;
+                d.end_arrive_qty = d.arrive_qty;
+                d.end_arrive_tp = d.arrive_tp;
+                d.end_deduct_qty = d.deduct_qty;
+                d.end_deduct_tp = d.deduct_tp;
+                d.arrive_qty = 0;
+                d.arrive_tp = 0;
+                d.deduct_qty = 0;
+                d.deduct_tp = 0;
+            }
+            return data;
+        }
         async _loadStagesJgclData(tender, stages, preStage, endStage) {
             // todo
             return [];
         }
         async _loadJgclData(tender, filter) {
             return filter.type === 'stage'
-                ? await this._loadStageJgclData(tender, filter.stage)
+                ? (filter.stage.__fake ? await this._loadFakeStageJgclData(tender, filter.stage) : await this._loadStageJgclData(tender, filter.stage))
                 : await this._loadStagesJgclData(tender, filter.stages, filter.preStage, filter.endStage);
         };
 
@@ -485,13 +574,27 @@ module.exports = app => {
             }
             return data;
         }
+        async _loadFakeStageYgclData(tender, stage) {
+            if (!stage) return [];
+
+            const data = await this.ctx.service.stageYjcl.getStageData(stage);
+            for (const d of data) {
+                d.end_qty = this.ctx.helper.add(d.pre_qty, d.qty);
+                d.end_tp = this.ctx.helper.add(d.pre_tp, d.tp);
+                d.pre_qty = d.end_qty;
+                d.pre_tp = d.pre_tp;
+                d.qty = 0;
+                d.tp = 0;
+            }
+            return data;
+        }
         async _loadStagesYgclData(tender, stages, preStage, endStage) {
             // todo
             return [];
         }
         async _loadYjclData(tender, filter) {
             return filter.type === 'stage'
-                ? await this._loadStageYgclData(tender, filter.stage)
+                ? (filter.stage.__fake ? await this._loadFakeStageYgclData(tender, filter.stage) : await this._loadStageYgclData(tender, filter.stage))
                 : await this._loadStagesYgclData(tender, filter.stages, filter.preStage, filter.endStage);
         };
 
@@ -527,13 +630,27 @@ module.exports = app => {
             }
             return data;
         }
+        async _loadFakeStageSafeProdData(tender, stage) {
+            if (!stage) return [];
+
+            const data = await this.ctx.service.stageSafeProd.getStageData(stage);
+            for (const d of data) {
+                d.pre_qty = d.qty;
+                d.pre_tp = d.tp;
+                d.end_qty = d.qty;
+                d.end_tp = d.tp;
+                d.qty = 0;
+                d.tp = 0;
+            }
+            return data;
+        }
         async _loadStagesSafeProdData(tender, stages, preStage, endStage) {
             // todo
             return [];
         }
         async _loadSafeProdData(tender, filter) {
             return filter.type === 'stage'
-                ? await this._loadStageSafeProdData(tender, filter.stage)
+                ? (filter.stage.__fake ? await this._loadFakeStageSafeProdData(tender, filter.stage) : await this._loadStageSafeProdData(tender, filter.stage))
                 : await this._loadStagesSafeProdData(tender, filter.stages, filter.preStage, filter.endStage);
         };
 
@@ -553,13 +670,27 @@ module.exports = app => {
             }
             return data;
         }
+        async _loadFakeStageTempLandData(tender, stage) {
+            if (!stage) return [];
+
+            const data = await this.ctx.service.stageTempLand.getStageData(stage);
+            for (const d of data) {
+                d.pre_qty = d.qty;
+                d.pre_tp = d.tp;
+                d.end_qty = d.qty;
+                d.end_tp = d.tp;
+                d.qty = 0;
+                d.tp = 0;
+            }
+            return data;
+        }
         async _loadStagesTempLandData(tender, stages, preStage, endStage) {
             // todo
             return [];
         }
         async _loadTempLandData(tender, filter) {
             return filter.type === 'stage'
-                ? await this._loadStageTempLandData(tender, filter.stage)
+                ? (filter.stage.__fake ? await this._loadFakeStageTempLandData(tender, filter.stage) : await this._loadStageTempLandData(tender, filter.stage))
                 : await this._loadStagesTempLandData(tender, filter.stages, filter.preStage, filter.endStage);
         };
 
@@ -577,13 +708,24 @@ module.exports = app => {
             }
             return data;
         }
+        async _loadFakeStageOtherData(tender, stage) {
+            if (!stage) return [];
+
+            const data = await this.ctx.service.stageOther.getStageData(stage);
+            for (const d of data) {
+                d.pre_tp = pd.tp;
+                d.end_tp = pd.tp;
+                pd.tp = 0;
+            }
+            return data;
+        }
         async _loadStagesOtherData(tender, stages, preStage, endStage) {
             // todo
             return [];
         }
         async _loadOtherData(tender, filter) {
             return filter.type === 'stage'
-                ? await this._loadStageOtherData(tender, filter.stage)
+                ? (filter.stage.__fake ? await this._loadFakeStageOtherData(tender, filter.stage) : await this._loadStageOtherData(tender, filter.stage))
                 : await this._loadStagesOtherData(tender, filter.stages, filter.preStage, filter.endStage);
         };
         async _loadTenderData(tid, filter, stageInfo) {

+ 6 - 0
app/public/js/shares/tender_select_multi.js

@@ -185,6 +185,12 @@ const TenderSelectMulti = function (setting) {
                         toastr.warning('请选择 汇总年月');
                         return;
                     }
+                } else if (stage.type === 'fake-month') {
+                    stage.month = $('#gather-fake-month').val();
+                    if (stage.month === '') {
+                        toastr.warning('请选择 汇总年月');
+                        return;
+                    }
                 } else if (stage.type === 'zone') {
                     stage.zone = $('#gather-zone').val();
                     if (stage.zone === '') {

+ 1 - 1
app/service/stage_bonus.js

@@ -86,7 +86,7 @@ module.exports = app => {
             const datas = data instanceof Array ? data : [data];
             const insertData = [];
             for (const d of datas) {
-                if (!d.name || !d.order) throw '新增甲供材料,提交的数据错误';
+                if (!d.name || !d.order) throw '新增奖罚金,提交的数据错误';
                 const nd = {
                     id: this.uuid.v4(),
                     tid: this.ctx.tender.id,

+ 9 - 0
app/view/spss/spss_select_modal.ejs

@@ -37,6 +37,10 @@
                                 <input class="form-check-input" type="radio" id="tsm-source-under-month" value="under-month" name="tsm-source">
                                 <label class="form-check-label" for="tsm-source-under-month">截止月</label>
                             </div>
+                            <div class="form-check form-check-inline" stage-type="fake-month">
+                                <input class="form-check-input" type="radio" id="tsm-source-fake-month" value="fake-month" name="tsm-source">
+                                <label class="form-check-label" for="tsm-source-fake-month">虚拟月</label>
+                            </div>
                         </div>
                     </div>
                     <div class="form-row align-items-center mb-2" id="tsm-stage-info-detail">
@@ -53,6 +57,11 @@
                                     <input id="gather-under-month" class="datepicker-here form-control mt-0" 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-fake-month" name="gather-type" style="display: none">
+                                <div class="input-group input-group-sm">
+                                    <input id="gather-fake-month" class="datepicker-here form-control mt-0" 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" name="gather-type" style="display: none">
                                 <div class="input-group input-group-sm">
                                     <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">