| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 | 'use strict';/** * * * @author Mai * @date * @version */const materialConst = require('../../const/material');const Ledger = require('../../lib/ledger');const billsFields = (function () {    const cur = ['contract_qty', 'contract_tp', 'contract_expr', 'qc_qty', 'qc_tp', 'gather_qty', 'gather_tp', 'postil'];    const pre = ['pre_contract_qty', 'pre_contract_tp', 'pre_qc_qty', 'pre_qc_tp', 'pre_gather_qty', 'pre_gather_tp'];    const end = ['end_contract_qty', 'end_contract_tp', 'end_qc_qty', 'end_qc_tp', 'end_gather_qty', 'end_gather_tp'];    const final = ['final_tp', 'final_ratio'];    const stageDgn = ['deal_dgn_qty1', 'deal_dgn_qty2', 'c_dgn_qty1', 'c_dgn_qty2'];    const stage = cur.concat(pre, end, final);    const stageEnd = pre.concat(end, final);    const bgl = ['qc_bgl_code'];    const leafXmj = ['leaf_xmj_id'];    return {cur, pre, end, final, stageDgn, stage, stageEnd, bgl, leafXmj};})();const posFields = (function () {    const cur = ['contract_qty', 'qc_qty', 'gather_qty', 'postil'];    const pre = ['pre_contract_qty', 'pre_qc_qty', 'pre_gather_qty'];    const end = ['end_contract_qty', 'end_qc_qty', 'end_gather_qty'];    const final = ['final_ratio'];    const stage = cur.concat(pre, end, final);    const stageEnd = pre.concat(end, final);    const bgl = ['qc_bgl_code'];    return {cur, pre, end, final, stage, stageEnd, bgl};})();class ReportMemoryMaterial {    constructor(ctx) {        this.ctx = ctx;    }    _getNewPos(updateFields) {        const helper = this.ctx.helper;        return new Ledger.pos({            id: 'id', ledgerId: 'lid',            updateFields: ['contract_qty', 'qc_qty', 'postil'],            calc: function (p) {                p.pre_gather_qty = helper.add(p.pre_contract_qty, p.pre_qc_qty);                p.gather_qty = helper.add(p.contract_qty, p.qc_qty);                p.end_contract_qty = helper.add(p.pre_contract_qty, p.contract_qty);                p.end_qc_qty = helper.add(p.pre_qc_qty, p.qc_qty);                p.end_gather_qty = helper.add(p.pre_gather_qty, p.gather_qty);            }        });    }    _getNewBillsTree(calcFields) {        return new Ledger.billsTree(this.ctx, {            id: 'ledger_id',            pid: 'ledger_pid',            order: 'order',            level: 'level',            rootId: -1,            keys: ['id', 'tender_id', 'ledger_id'],            stageId: 'id',            calcFields: calcFields || ['deal_tp', 'total_price', 'contract_tp', 'qc_tp', 'gather_tp', 'pre_contract_tp', 'pre_qc_tp', 'pre_gather_tp'],            calc: function (node, helper) {                if (node.children && node.children.length === 0) {                    node.pre_gather_qty = helper.add(node.pre_contract_qty, node.pre_qc_qty);                    node.gather_qty = helper.add(node.contract_qty, node.qc_qty);                    node.end_contract_qty = helper.add(node.pre_contract_qty, node.contract_qty);                    node.end_qc_qty = helper.add(node.pre_qc_qty, node.qc_qty);                    node.end_gather_qty = helper.add(node.pre_gather_qty, node.gather_qty);                }                node.pre_gather_tp = helper.add(node.pre_contract_tp, node.pre_qc_tp);                node.gather_tp = helper.add(node.contract_tp, node.qc_tp);                node.end_contract_tp = helper.add(node.pre_contract_tp, node.contract_tp);                node.end_qc_tp = helper.add(node.pre_qc_tp, node.qc_tp);                node.end_gather_tp = helper.add(node.pre_gather_tp, node.gather_tp);                node.final_tp = helper.add(node.total_price, node.end_qc_tp);                node.final_ratio = helper.mul(helper.div(node.end_gather_tp, node.final_tp, 4), 100);            }        });    }    _checkFieldsExist(source, check) {        for (const s of source) {            if (check.indexOf(s) >= 0) {                return true;            }        }        return false;    }    async getSelectMaterialAuditors(tid, material_order, fields) {        await this.ctx.service.material.checkMaterial(tid, material_order);        const auditors = await this.ctx.service.materialAudit.getFinalAuditGroup(this.ctx.material.id, this.ctx.material.curTimes);        const user = await this.ctx.service.projectAccount.getDataById(this.ctx.material.user_id);        const result = [{            aid: user.id,            name: user.name,            company: user.company,            role: user.role,            mobile: user.mobile,            telephone: user.telephone,            sign_path: user.sign_path,            opinion: user.opinion,            end_time: auditors && auditors.length > 0 ? auditors[0].begin_time : null,            sort: 0,        }, ...auditors];        return result;    }    async getMaterial(tender_id, material_order, fields) {        const result = await this.ctx.service.material.getValidMaterials(tender_id);        if (this._checkFieldsExist(fields, ['checked_time'])) {            for (const r of result) {                const auditors = await this.ctx.service.materialAudit.getFinalAuditGroup(r.id, r.curTimes || r.times);                r.checked_time = !r.curTimes ? auditors[auditors.length - 1].end_time : null;            }        }        return result;    }    _completeMaterialGl(materialGl) {        const tTypeStr = [], mTypeStr = [];        for (const t of materialConst.t_type) {            tTypeStr[t.value] = t.text;        }        for (const m of materialConst.m_type) {            mTypeStr[m.value] = m.text;        }        for (const gl of materialGl) {            gl.tp = this.ctx.helper.mul(gl.quantity, gl.m_spread, 2);            gl.t_type_str = tTypeStr[gl.t_type];            gl.m_type_str = mTypeStr[gl.m_type];            gl.end_tp = this.ctx.helper.add(gl.tp, gl.pre_tp);        }    }    async _loadMaterialMonth(material, gl) {        const materialMonth = await this.ctx.service.materialMonth.getAllDataByCondition({            where: { mid: material.id },            orders: [['mb_id', 'asc'], ['yearmonth', 'asc']],        });        const month = this.ctx.helper._.uniq(materialMonth.map(x => { return x.yearmonth; }));        let g;        for (const mm of materialMonth) {            if (!g || g.id !== mm.mb_id) g = gl.find(x => { return mm.mb_id === x.id; });            if (!g.month_msg_tp) g.month_msg_tp = [];            if (!g.month) g.month = month.concat([]);            const index = month.indexOf(mm.yearmonth);            if (index >= 0) g.month_msg_tp[index] = mm.msg_tp;        }    }    async getMaterialGl(tender_id, material_order, fields) {        const materials = await this.ctx.service.material.getAllDataByCondition({            where: {tid: tender_id},            orders: [['order', 'desc']],        });        if (materials.length === 0) return [];        let result, material;        if (materials[0].order === material_order) {            material = materials[0];            if (material.is_stage_self) {                const sql = 'SELECT msb.id, msb.tid, msb.mid, msb.ms_id, ms.sid, ms.`order` as s_order, mb.order, mb.t_type, mb.code, mb.name, mb.unit, mb.spec, mb.m_type,' +                    '    msb.quantity, mb.expr,' +                    '    mb.basic_price, mb.basic_times, ' +                    '    msb.msg_tp, msb.msg_times, msb.msg_spread, mb.m_up_risk, mb.m_down_risk, msb.m_spread, msb.m_tp, mb.pre_tp, msb.m_tax_tp, mb.tax_pre_tp, mb.origin, ' +                    '    msb.remark, msb.is_summary, mb.m_tax, mb.in_time, mb.origin' +                    `  FROM ${this.ctx.service.materialStageBills.tableName} msb` +                    `  LEFT JOIN ${this.ctx.service.materialBills.tableName} mb ON msb.mb_id = mb.id` +                    '  LEFT JOIN ' + this.ctx.service.materialStage.tableName + ' ms ON msb.ms_id = ms.id ' +                    `  WHERE msb.mid = ?` +                    '  ORDER By msb.ms_id, mb.order';                result = await this.ctx.app.mysql.query(sql, [material.id]);            } else {                result = await this.ctx.service.materialBills.getAllDataByCondition({                    where: {tid: tender_id}                });            }        } else {            material = this.ctx.helper._.find(materials, {order: material_order});            if (!material) return [];            if (material.is_stage_self) {                const sql = 'SELECT msb.id, msb.tid, msb.mid, msb.ms_id, ms.sid, ms.`order` as s_order, mb.order, mb.t_type, mb.code, mb.name, mb.unit, mb.spec, mb.m_type,' +                    '    msb.quantity, mbh.expr,' +                    '    mb.basic_price, mb.basic_times, ' +                    '    msb.msg_tp, msb.msg_times, msb.msg_spread, mbh.m_up_risk, mbh.m_down_risk, msb.m_spread, msb.m_tp, mbh.pre_tp, msb.m_tax_tp, mbh.tax_pre_tp, mbh.origin, ' +                    '    msb.remark, msb.is_summary, mbh.m_tax, mb.in_time, mbh.origin' +                    `  FROM ${this.ctx.service.materialStageBills.tableName} msb` +                    '  LEFT JOIN ' + this.ctx.service.materialBillsHistory.tableName + ' mbh ON msb.mb_id = mbh.mb_id AND msb.mid = mbh.mid' +                    '  LEFT JOIN ' + this.ctx.service.materialBills.tableName + ' mb ON msb.mb_id = mb.id ' +                    '  LEFT JOIN ' + this.ctx.service.materialStage.tableName + ' ms ON msb.ms_id = ms.id ' +                    '  WHERE msb.mid = ?'+                    '  ORDER By msb.ms_id, mb.order';                result = await this.ctx.app.mysql.query(sql, [material.id]);            } else {                const sql = 'SELECT mb.id, mb.tid, mb.mid, mb.order, mb.t_type, mb.code, mb.name, mb.unit, mb.spec, mb.m_type,' +                    '    mbh.quantity, mbh.expr,' +                    '    mb.basic_price, mb.basic_times, ' +                    '    mbh.msg_tp, mbh.msg_times, mbh.msg_spread, mbh.m_up_risk, mbh.m_down_risk, mbh.m_spread, mbh.m_tp, mbh.pre_tp, mbh.m_tax_tp, mbh.tax_pre_tp, mbh.origin, ' +                    '    mb.remark, mb.is_summary, mbh.m_tax, mb.in_time, mbh.origin' +                    '  FROM ' + this.ctx.service.materialBillsHistory.tableName + ' mbh ' +                    '  LEFT JOIN ' + this.ctx.service.materialBills.tableName + ' mb ON mbh.mb_id = mb.id ' +                    '  WHERE mbh.tid = ? And mbh.mid = ?'+                    '  ORDER By mb.order';                result = await this.ctx.app.mysql.query(sql, [tender_id, material.id]);            }        }        this._completeMaterialGl(result);        if (this._checkFieldsExist(fields, ['month_msg_tp', 'month'])) await this._loadMaterialMonth(material, result);        return result;    }    async getMaterialGlDetail(tender_id, material_order, fields) {        const material = await this.ctx.service.material.getDataByCondition({tid: tender_id, order: material_order});        if (!material) return [];        if (material.is_stage_self) {            return await this.ctx.service.materialList.getMaterialStageData(tender_id, material.id);        } else {            return await this.ctx.service.materialList.getMaterialData(tender_id, material.id);        }    }    async getMaterialBills(tender_id, material_order, fields, showLevel) {        await this.ctx.service.tender.checkTender(tender_id);        const material = await this.ctx.service.material.getDataByCondition({tid: tender_id, order: material_order});        if (!material) return [];        try {            const billsData = await this.ctx.service.ledger.getData(tender_id);            if (this._checkFieldsExist(fields, billsFields.stage)) {                const curStage = await this.ctx.service.stageBills.getStagesData(tender_id, material.stage_id);                this.ctx.helper.assignRelaData(billsData, [                    {data: curStage, fields: ['contract_qty', 'contract_tp', 'contract_expr', 'qc_qty', 'qc_tp', 'postil'], prefix: '', relaId: 'lid'}                ]);            }            const billsTree = this._getNewBillsTree();            billsTree.loadDatas(billsData);            billsTree.calculateAll();            return showLevel ? billsTree.getDefaultDatasByLevel(this.ctx.tender.rpt_show_level) : billsTree.getDefaultDatas();        } catch(err) {            this.ctx.helper.log(err);            return [];        }    }    async getMaterialPos(tender_id, material_order, fields) {        const material = await this.ctx.service.material.getDataByCondition({tid: tender_id, order: material_order});        if (!material) return [];        try {            const posData = await this.ctx.service.pos.getAllDataByCondition({ where: {tid: tender_id }});            if (this._checkFieldsExist(fields, posFields.stage)) {                const curPosStage = await this.ctx.service.stagePos.getStagesData(tender_id, material.stage_id);                this.ctx.helper.assignRelaData(posData, [                    {data: curPosStage, fields: ['contract_qty', 'qc_qty', 'contract_expr', 'postil'], prefix: '', relaId: 'pid'}                ]);            }            const pos = this._getNewPos();            pos.loadDatas(posData);            pos.calculateAll();            return pos.getDatas();        } catch (err) {            this.ctx.helper.log(err);            return [];        }    }    async _getMaterialStageGatherBills(tender_id, stage_id, stage_order, stageSelf, stageIndex = 0) {        const decimal = this.materialGatherBase.decimal;        //const billsData = this.ctx.helper.clone(this.materialGatherBase.billsData);        const billsData = this.materialGatherBase.billsData;        billsData.forEach(x => {            for (const prop of ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp']) {                x[prop] = undefined;            }        });        const curStageBills = await this.ctx.service.stageBills.getStagesData(tender_id, stage_id);        this.ctx.helper.assignRelaData(billsData, [            { data: curStageBills, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: '', relaId: 'lid' },        ]);        const billsTree = this._getNewBillsTree();        billsTree.loadDatas(billsData);        billsTree.calculateAll();        //const posData = this.ctx.helper.clone(this.materialGatherBase.posData);        const posData = this.materialGatherBase.posData;        posData.forEach(x => {            for (const prop of ['contract_qty', 'qc_qty']) {                x[prop] = undefined;            }        });        const curStage = await this.ctx.service.stagePos.getStagesData(tender_id, stage_id);        this.ctx.helper.assignRelaData(posData, [            { data: curStage, fields: ['contract_qty', 'qc_qty'], prefix: '', relaId: 'pid' },        ]);        const pos = this._getNewPos();        pos.loadDatas(posData);        pos.calculateAll();        const gclGatherModel = require('../gcl_gather').gclGather;        const gatherUtil = new gclGatherModel(this.ctx);        gatherUtil.gatherObj(billsTree, pos);        const materialGl = stageSelf            ? this.materialGatherBase.materialGl.filter(x => { return x.sid === parseInt(stage_id); })            : this.materialGatherBase.materialGl;        if (stageIndex) materialGl.forEach(x => { x.s_index = stageIndex });        const materialNotJoin = this.materialGatherBase.materialNotJoin;        const helper = this.ctx.helper;        console.time('calcMaterialBills');        for (const g of gatherUtil.gclList) {            if (!g.contract_qty && !g.qc_qty) continue;            g.sid = stage_id;            g.sorder = stage_order;            g.s_index = stageIndex;            g.jiacha = 0;            for (const x of g.leafXmjs) {                x.sid = stage_id;                x.sorder = stage_order;                x.s_index = stageIndex;                x.jiacha = 0;                const mnj = materialNotJoin.find(m => {                    return m.gcl_id === x.org_gcl_id && m.xmj_id === x.id && (x.mx_id && x.mx_id !== x.id  ? x.mx_id === m.mx_id : true);                });                x.is_join = !mnj;                const list = materialGl.filter(gl => {                    return gl.gcl_id === x.org_gcl_id && gl.xmj_id === x.id && (x.mx_id && x.mx_id !== x.id ? x.mx_id === gl.mx_id : true);                });                list.forEach(l => { l.gather_gcl_id = x.gcl_id});                if (mnj) continue;                for (const l of list) {                    x.jiacha = helper.add(x.jiacha, helper.mul(helper.mul(x.gather_qty, l.quantity), l.m_spread));                }                x.jiacha = helper.round(x.jiacha, decimal.tp);                g.jiacha = helper.add(g.jiacha, x.jiacha);                g.jiacha_qty = helper.add(g.jiacha_qty, x.gather_qty);            }        }        console.timeEnd('calcMaterialBills');        return [gatherUtil.gclList, gatherUtil.leafXmjs];    }    async getMaterialGatherBills(tender_id, material_order) {        const materials = await this.ctx.service.material.getAllDataByCondition({            where: { tid: tender_id },            orders: [['order', 'desc']],        });        if (materials.length === 0) return {};        const material = await this.ctx.service.material.getDataByCondition({ tid: tender_id, order: material_order });        this.materialGatherBase = {};        this.materialGatherBase.decimal = material.decimal ? JSON.parse(material.decimal) : materialConst.decimal;        try {            // 获取基础数据            this.materialGatherBase.billsData = await this.ctx.service.ledger.getData(tender_id);            this.materialGatherBase.posData = await this.ctx.service.pos.getPosData({ tid: tender_id });            if (material.is_stage_self) {                this.materialGatherBase.materialGl = material_order === materials[0].order                    ? await this.ctx.service.materialList.getMaterialStageData(tender_id, material.id)                    : await this.ctx.service.materialList.getPreMaterialStageData(tender_id, material.id);            } else {                this.materialGatherBase.materialGl = material_order === materials[0].order                    ? await this.ctx.service.materialList.getMaterialData(tender_id, material.id)                    : await this.ctx.service.materialList.getPreMaterialData(tender_id, material.id);            }            this.materialGatherBase.materialNotJoin = await this.ctx.service.materialListNotjoin.getAllDataByCondition({ where: { mid: material.id } });            const mem_material_gather_bills = [], mem_material_gather_xmj = [];            if (material.is_stage_self) {                const stageIds = material.stage_id.split(',');                const stageOrders = material.s_order.split(',');                for (const [i, sid] of stageIds.entries()) {                    const [gclList, leafXmjs] = await this._getMaterialStageGatherBills(tender_id, sid, stageOrders[i], true, i + 1);                    mem_material_gather_bills.push(...gclList);                    mem_material_gather_xmj.push(...leafXmjs);                }            } else {                const [gclList, leafXmjs] = await this._getMaterialStageGatherBills(tender_id, material.stage_id, material.stage_order, false);                mem_material_gather_bills.push(...gclList);                mem_material_gather_xmj.push(...leafXmjs);            }            return {mem_material_gather_bills, mem_material_gather_xmj, mem_material_gather_gl: this.materialGatherBase.materialGl};        } catch (err) {            this.ctx.log(err);            return {};        }    }    async getMaterialStage(tender_id, material_order, fields) {        const material = await this.ctx.service.material.getDataByCondition({tid: tender_id, order: material_order});        if (!material) return [];        if (material.is_stage_self) {            return await this.ctx.service.materialStage.getAllDataByCondition({ where: { mid: material.id } });        } else {            return [{                id: -1, tid: material.id, mid: material.id, sid: material.stage_id, order: material.stage_order,                m_tp: material.m_tp, m_tax_tp: material.m_tax_tp,            }];        }    }}module.exports = ReportMemoryMaterial;
 |