'use strict';

/**
 * stage_pos_final 期-部位明细-最终数据(截止本期)
 *
 * @author Mai
 * @date
 * @version
 */

const timesLen = require('../const/audit').stage.timesLen;

module.exports = app => {

    class StagePosFinal extends app.BaseService {
        /**
         * 构造函数
         *
         * @param {Object} ctx - egg全局变量
         * @return {void}
         */
        constructor(ctx) {
            super(ctx);
            this.tableName = 'stage_pos_final';
        }

        /**
         * 获取截止本期数据
         * @param {Object} tender - 标段
         * @param {Object} stage - 本期
         * @returns {Promise<void>}
         */
        async getFinalData(tender, stage) {
            const sql = 'SELECT Pos.* FROM ' +
                //'  (SELECT pid, contract_qty, qc_qty, sorder FROM ' + this.tableName + ' WHERE tid = ?) As Pos' +
                this.tableName + ' As Pos' +
                '  INNER JOIN ( ' +
                '    SELECT MAX(`sorder`) As `sorder`, `pid` From ' + this.tableName +
                '      WHERE tid = ? AND sorder < ?' +
                '      GROUP BY `pid`' +
                '  ) As MaxFilter ' +
                '  ON Pos.sorder = MaxFilter.sorder And Pos.pid = MaxFilter.pid';
            const sqlParam = [tender.id, tender.id, stage.order];
            return await this.db.query(sql, sqlParam);
        }

        /**
         * 生成本期最终数据
         * @param transaction - 所属事务
         * @param {Number} tender - 标段
         * @param {Number}stage - 本期
         * @returns {Promise<void>}
         */
        async generateFinalData(transaction, tender, stage) {
            if (!transaction || !tender || !stage) {
                throw '数据错误';
            }
            if (stage.order > 1) {
                const cur = await this.ctx.service.stagePos.getLastestStageData(tender.id, stage.id);
                if (!cur || cur.length === 0) return;
                const pre = await this.getFinalData(tender, stage);
                for (const c of cur) {
                    delete c.id;
                    delete c.said;
                    delete c.times;
                    delete c.order;
                    delete c.postil;
                    c.sorder = stage.order;
                    const p = this.ctx.helper._.find(pre, {pid: cur.pid});
                    if (!p) continue;
                    c.contract_qty = this.ctx.helper.add(c.contract_qty, p.contract_qty);
                    c.qc_qty = this.ctx.helper.add(c.qc_qty, p.qc_qty);
                    pre.splice(pre.index(p), 1);
                }
                await transaction.insert(this.tableName, cur);
                //await transaction.insert(this.tableName, cur.concat(pre));
            } else {
                const sql = 'Insert Into ??(tid, sid, lid, pid, sorder, contract_qty, qc_qty)' +
                            '  SELECT p.tid, p.sid, p.lid, p.pid, ? As `sorder`, p.contract_qty, p.qc_qty' +
                            '  FROM ' + this.ctx.service.stagePos.tableName + ' AS p' +
                            '  INNER JOIN(' +
                            '    SELECT Max(`times` * ' + timesLen +' + `order`) As `flow`, `pid` FROM ' + this.ctx.service.stagePos.tableName +
                            '    WHERE `sid` = ?' +
                            '    GROUP By `pid`) As MF' +
                            '  ON (p.times * ' + timesLen + ' + p.order) = MF.flow AND p.pid = MF.pid' +
                            '  WHERE p.sid = ?';
                const sqlParam = [this.tableName, stage.order, stage.id, stage.id];
                await transaction.query(sql, sqlParam);
            }
        }
    }

    return StagePosFinal;
}