'use strict';

/**
 * stage_bills_final 期-清单-最终数据(截止本期)
 *
 * @author Mai
 * @date
 * @version
 */
const timesLen = require('../const/audit').stage.timesLen;

module.exports = app => {

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

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

        /**
         * 生成本期最终数据
         * @param transaction - 所属事务
         * @param {Object} tender - 标段
         * @param {Object} stage - 本期
         * @returns {Promise<void>}
         */
        async generateFinalData(transaction, tender, stage) {
            if (!transaction || !tender || !stage) {
                throw '数据错误';
            }
            if (stage.order > 1) {
                const cur = await this.ctx.service.stageBills.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;
                    const p = this.ctx.helper._.find(pre, {lid: cur.lid});
                    if (!p) continue;
                    c.contract_qty = this.ctx.helper.add(c.contract_qty, p.contract_qty);
                    c.contract_tp = this.ctx.helper.add(c.contract_tp, p.contract_tp);
                    c.qc_qty = this.ctx.helper.add(c.qc_qty, p.qc_qty);
                    c.qc_tp = this.ctx.helper.add(c.qc_tp, p.qc_tp);
                }
                await transaction.insert(this.tableName, cur);
            } else {
                const sql = 'Insert Into ??(tid, sid, lid, sorder, contract_qty, contract_tp, qc_qty, qc_tp)' +
                    '  SELECT b.tid, b.sid, b.lid, ? As `sorder`, b.contract_qty, b.contract_tp, b.qc_qty, b.qc_tp' +
                    '  FROM ' + this.ctx.service.stageBills.tableName + ' AS b' +
                    '  INNER JOIN(' +
                    '    SELECT Max(`times` * ' + timesLen + ' + `order`) As `flow`, `lid` FROM ' + this.ctx.service.stageBills.tableName +
                    '    WHERE `sid` = ?' +
                    '    GROUP By `lid`) As MF' +
                    '  ON (b.times * ' + timesLen + ' + b.order) = MF.flow AND b.lid = MF.lid' +
                    '  WHERE b.sid = ?';
                const sqlParam = [this.tableName, stage.order, stage.id, stage.id];
                await transaction.query(sql, sqlParam);
            }
        }
    }

    return StageBillsFinal;
}