Просмотр исходного кода

1. 成本分析,台账明细汇总算法调整
2. 成本分析,关联成本类型可选,兼容成本报审、财务账面两种
3. 财务账面,限制关联成本期,不允许修改

MaiXinRong 22 часов назад
Родитель
Сommit
eb4288eb32

+ 7 - 4
app/controller/cost_controller.js

@@ -129,12 +129,13 @@ module.exports = app => {
                 const validLedgerStages = await this.ctx.service.costStage.getAllCheckedStages(ctx.tender.id, 'ledger', 'DESC');
                 for (const vls of validLedgerStages) {
                     vls.beenRela = stages.findIndex(x => { return x.rela_stage.sid === vls.id; }) >= 0;
+                    vls.canRela = vls.stage_order === stages.length + 1;
                 }
                 const renderData = {
                     stage_type,
                     auditType: audit.auditType,
                     stages,
-                    validLedgerStages: validLedgerStages.filter(x => { return !x.beenRela; }),
+                    validLedgerStages: validLedgerStages.filter(x => { return x.canRela; }), //validLedgerStages.filter(x => { return !x.beenRela; }),
                     auditConst: audit.common,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.cost.cost_stage)
                 };
@@ -149,13 +150,15 @@ module.exports = app => {
                 const stage_type = this.ctx.service.costStage.stageType.analysis.key;
                 const stages = await this.getTypeStages(ctx, stage_type);
                 // todo 兼容以ledger做关联的情况,届时只需在标段或者项目上设置这个类型即可。
-                const analysisType = 'book';
+                const analysisType = this.ctx.subProject.fun_rela.costAnalysisType;
                 let validRelaStages = await this.ctx.service.costStage.getAllCheckedStages(ctx.tender.id, analysisType, 'DESC');
                 if (stages.length > 0) {
                     const checkedStage = stages.find(x => { return x.audit_status === audit.common.status.checked; });
                     if (checkedStage) validRelaStages = validRelaStages.filter( x => { return x.stage_order > checkedStage.rela_stage.sorder; });
                 }
                 const renderData = {
+                    analysisType,
+                    analysisTypeStr: this.ctx.service.costStage.stageType[analysisType].name,
                     stage_type,
                     auditType: audit.auditType,
                     stages,
@@ -191,10 +194,10 @@ module.exports = app => {
                     if (!ledgerStage) throw '选择的关联成本不存在';
                     newStage = await ctx.service.costStage.add(ctx.tender.id, stage_type, ledgerStage.stage_date, { sid: ledgerStage.id, sorder: ledgerStage.stage_order });
                 } else if (stage_type === 'analysis') {
+                    const analysisType = this.ctx.subProject.fun_rela.costAnalysisType;
+                    if (analysisType !== ctx.request.body.analysis_type) throw '成本分析应关联的成本类型发生改变,请在界面刷新后再试';
                     const stage_order = ctx.request.body.stage;
                     if (!stage_order) throw '请选择关联期';
-                    // todo 兼容以ledger做关联的情况,届时只需在标段或者项目上设置这个类型即可。
-                    const analysisType = 'book';
                     const relaStage = await ctx.service.costStage.getStageByOrder(ctx.tender.id, analysisType, stage_order);
                     if (!relaStage) throw '选择的关联期不存在';
                     newStage = await ctx.service.costStage.add(ctx.tender.id, stage_type, relaStage.stage_date, { sid: relaStage.id, sorder: relaStage.stage_order });

+ 3 - 3
app/service/cost_stage.js

@@ -25,9 +25,9 @@ module.exports = app => {
             super(ctx);
             this.tableName = 'cost_stage';
             this.stageType = {
-                ledger: { key: 'ledger', decimal: { tp: 6, tax: 2 }, shenpi_status: 'cost_stage_ledger', push_type: 'costStageLedger', dataService: 'costStageLedger', detailService: 'costStageDetail' },
-                book: { key: 'book', decimal: { tp: 6 }, shenpi_status: 'cost_stage_book', push_type: 'costStageBook', dataService: 'costStageBook', detailService: 'costStageBookDetail' },
-                analysis: { key: 'analysis', decimal: { tp: 6 }, shenpi_status: 'cost_stage_analysis', push_type: 'costStageAnalysis', dataService: 'costStageAnalysis', detailService: 'costStageAnalysisDetail' },
+                ledger: { key: 'ledger', name: '成本报审', decimal: { tp: 6, tax: 2 }, shenpi_status: 'cost_stage_ledger', push_type: 'costStageLedger', dataService: 'costStageLedger', detailService: 'costStageDetail' },
+                book: { key: 'book', name: '财务账面', decimal: { tp: 6 }, shenpi_status: 'cost_stage_book', push_type: 'costStageBook', dataService: 'costStageBook', detailService: 'costStageBookDetail' },
+                analysis: { key: 'analysis', name: '成本分析', decimal: { tp: 6 }, shenpi_status: 'cost_stage_analysis', push_type: 'costStageAnalysis', dataService: 'costStageAnalysis', detailService: 'costStageAnalysisDetail' },
             };
         }
 

+ 4 - 4
app/service/cost_stage_analysis.js

@@ -102,18 +102,18 @@ module.exports = app => {
         }
 
         async getCostStageData(costStage) {
-            if (costStage.rela_stage.sid) costStage.relaStage = await this.ctx.service.costStage.getStage(costStage.rela_stage.sid);
+            if (costStage.stage_type === 'book') costStage.relaStage = await this.ctx.service.costStage.getStage(costStage.rela_stage.sid);
             const ledgerData = costStage.relaStage
                 ? await this.ctx.service.costStageLedger.getReadData(costStage.relaStage)
                 : await this.ctx.service.costStageLedger.getReadData(costStage);
-            if (costStage.relaStage) {
+            if (costStage.stage_type === 'book') {
                 const bookData = await this.ctx.service.costStageBook.getReadData(costStage);
                 this.ctx.helper.assignRelaData(ledgerData, [
                     { data: bookData, fields: ['end_in_tp', 'end_in_excl_tax_tp'], prefix: '', relaId: 'ledger_id' },
                 ]);
             }
-            const detail = costStage.relaStage
-                ? await this.ctx.service.costStageBookDetail.getEndData(costStage.relaStage)
+            const detail = costStage.stage_type === 'book'
+                ? await this.ctx.service.costStageBookDetail.getEndData(costStage)
                 : await this.ctx.service.costStageDetail.getEndData(costStage);
             const ledger = new Ledger.baseTree(this.ctx, {
                 id: 'tree_id', pid: 'tree_pid', order: 'tree_order',

+ 3 - 0
app/service/cost_stage_book_detail.js

@@ -57,6 +57,9 @@ module.exports = app => {
             return result;
         }
         async getEndData(stage) {
+            if (!stage) return [];
+            if (stage.stage_type !== 'book') throw '关联财务账面错误';
+
             const allStages = await this.db.query(`SELECT rela_stage FROM ${this.ctx.service.costStage.tableName} WHERE tid = ? AND stage_type = 'book' AND stage_order <= ?`, [stage.tid, stage.stage_order]);
             const relaStageIds = allStages.map(x => {
                 const rs = JSON.parse(x.rela_stage);

+ 1 - 0
app/service/cost_stage_detail.js

@@ -105,6 +105,7 @@ module.exports = app => {
         }
         async getEndData(stage) {
             if (stage) return [];
+            if (stage.stage_type !== 'ledger') throw '关联成本报审错误';
 
             const allStages = await this.db.query(`SELECT id FROM ${this.ctx.service.costStage.tableName} WHERE tid = ? AND stage_type = 'ledger' AND stage_order <= ?`, [stage.tid, stage.stage_order]);
             const relaStageIds = allStages.map(x => {

+ 2 - 0
app/service/sub_project.js

@@ -20,6 +20,7 @@ const defaultFunRela = {
     needGcl: false,
     budgetZb: true,
     budgetCtrl: true,
+    costAnalysisType: 'book',
 };
 const funSet = require('../const/fun_set');
 const defaultFunSet = funSet.defaultInfo;
@@ -738,6 +739,7 @@ module.exports = app => {
                     needGcl: data.needGcl, budgetCtrl: data.budgetCtrl, budgetZb: data.budgetZb,
                     minusNoValue: data.minusNoValue,
                     lockPayExpr: data.lockPayExpr, showMinusCol: data.showMinusCol, ledgerAss: data.ledgerAss,
+                    costAnalysisType: data.costAnalysisType,
                 }),
             });
             return result.affectedRows === 1;

+ 2 - 1
app/view/cost/analysis_list_modal.ejs

@@ -11,7 +11,7 @@
                     <input type="hidden" value="<%- (stages.length + 1) %>" name="stage_order">
                 </div>
                 <div class="form-group form-group-sm">
-                    <label>关联成本</label>
+                    <label>关联成本(<%- analysisTypeStr %>)</label>
                     <select class="form-control form-control-sm" name="stage">
                         <% for (const s of validRelaStages) { %>
                         <option value="<%- s.stage_order %>">第 <%- s.stage_order %> 期</option>
@@ -22,6 +22,7 @@
             <div class="modal-footer">
                 <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />
                 <input type="hidden" name="stage_type" value="<%- stage_type %>" />
+                <input type="hidden" name="analysis_type" value="<%- analysisType %>" />
                 <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
                 <button type="submit" class="btn btn-sm btn-primary">确定</button>
             </div>

+ 1 - 1
app/view/cost/book_list_modal.ejs

@@ -12,7 +12,7 @@
                 </div>
                 <div class="form-group form-group-sm">
                     <label>关联成本</label>
-                    <select class="form-control form-control-sm" name="stage">
+                    <select class="form-control form-control-sm" name="stage" readonly="">
                         <% for (const s of validLedgerStages) { %>
                         <option value="<%- s.stage_order %>">第 <%- s.stage_order %> 期</option>
                         <% } %>

+ 24 - 0
app/view/sp_setting/fun.ejs

@@ -385,6 +385,29 @@
                                 </div>
                             </div>
                         </div>
+                        <div class="row">
+                            <div class="col-6">
+                                <div class="card mb-3">
+                                    <div class="card-header d-flex justify-content-between">
+                                        <div>成本管理</div>
+                                    </div>
+                                    <div class="card-body">
+                                        <div class="alert alert-dark py-1 px-2 mb-2" role="alert">成本分析-关联成本类型</div>
+                                        <div class="d-flex">
+                                            <div class="form-check form-check-inline">
+                                                <input class="form-check-input" type="radio" id="radio_ledger" value="ledger" <% if (funRela.costAnalysisType === 'ledger') { %>checked<% } %> name="cost_analysis_type" onchange="updateSetting();">
+                                                <label class="form-check-label" for="radio_ledger">成本报审</label>
+                                            </div>
+                                            <div class="form-check form-check-inline">
+                                                <input class="form-check-input" type="radio" id="radio_book" value="book" <% if (funRela.costAnalysisType === 'book') { %>checked<% } %> name="cost_analysis_type" onchange="updateSetting();">
+                                                <label class="form-check-label" for="radio_book">财务账面</label>
+                                            </div>
+                                            <label class="form-text alert alert-warning py-1 px-2 mb-2"><i class="fa fa-exclamation-circle mr-1"></i>切换关联成本,对已创建的成本分析期数据无效。</label>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
                     </div>
                 </div>
             </div>
@@ -647,6 +670,7 @@
         }
         postData('/sp/<%- ctx.subProject.id %>/setting/fun/update', {
             imType: parseInt($('[name=im_type]:checked').val()),
+            costAnalysisType: $('[name=cost_analysis_type]:checked').val(),
             banOver: $('[name=ban_over]')[0].checked,
             hintOver: $('#hint_over')[0].checked,
             banMinusChangeBills: $('[name=ban_minus_cb]')[0].checked,

+ 3 - 0
sql/update.sql

@@ -576,6 +576,9 @@ CREATE TABLE `zh_contract_supplement_attachment` (
   PRIMARY KEY (`id`) USING BTREE,
   KEY `idx_cid` (`csid`) USING BTREE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='合同补充附件表';
+
+ALTER TABLE `zh_sub_project`
+MODIFY COLUMN `fun_rela` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '功能设置(json.stringify)' AFTER `page_show`;
 ------------------------------------
 -- 表数据
 ------------------------------------