'use strict'; /** * * * @author Mai * @date * @version */ const RptMemBase = require('./base'); const bindData = { materialGather: ['mem_material_gather_bills', 'mem_material_gather_xmj', 'mem_material_gather_gl'], }; 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 rptMemChange extends RptMemBase { constructor(ctx) { super(ctx, bindData); } async doCheckMaterial(materialId) { if (this.ctx.material) return; this.ctx.material = await this.ctx.service.material.getDataByCondition({ id: materialId }); } async doCheckTender(tenderId) { if (this.ctx.tender) return; this.ctx.tender = { id: tenderId }; this.ctx.tender.data = await this.ctx.service.tender.getTender(tenderId); this.ctx.tender.info = await this.ctx.service.tenderInfo.getTenderInfo(tenderId); } async doBeforeLoadReport(params) { await this.doCheckMaterial(params.material_id); await this.doCheckTender(this.ctx.material.tid); } _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.gather_minus_qty = helper.add(p.gather_qty, p.qc_minus_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.gather_minus_qty = helper.add(node.gather_qty, node.qc_minus_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); } }); } async getMaterialAuditors() { 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, tp_data: this.ctx.material.tp_data, }, ...auditors]; return result; } 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; } } _completeMaterialGl(materialGl, decimal) { 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, decimal.tp); 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 getMaterialGl(fields) { if (!this.ctx.material) return []; const materials = await this.ctx.service.material.getAllDataByCondition({ where: {tid: this.ctx.material.tid}, orders: [['order', 'desc']], }); if (materials.length === 0) return []; let result, material, decimal; material = this.ctx.material; if (materials[0].order === material.order) { decimal = material.decimal ? JSON.parse(material.decimal) : { qty: 3, up: 3, tp: 2 }; 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: material.tid} }); } } else { decimal = material.decimal ? JSON.parse(material.decimal) : { tp: 2 }; 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, [material.tid, material.id]); } } this._completeMaterialGl(result, decimal); if (this._checkFieldsExist(fields, ['month_msg_tp', 'month'])) await this._loadMaterialMonth(material, result); return result; } async getMaterialGlDetail(fields) { const material = this.ctx.material; if (!material) return []; if (material.is_stage_self) { return await this.ctx.service.materialList.getMaterialStageData(material.tid, material.id); } else { return await this.ctx.service.materialList.getMaterialData(material.tid, material.id); } } async getMaterialBills(fields, showLevel) { const material = this.ctx.material; if (!material) return []; try { const billsData = await this.ctx.service.ledger.getData(material.tid); if (this._checkFieldsExist(fields, billsFields.stage)) { const curStage = await this.ctx.service.stageBills.getStagesData(material.tid, material.stage_id); this.ctx.helper.assignRelaData(billsData, [ {data: curStage, fields: ['contract_qty', 'contract_tp', 'contract_expr', 'qc_qty', 'qc_tp', 'qc_minus_qty', '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(fields) { const material = this.ctx.material; if (!material) return []; try { const posData = await this.ctx.service.pos.getAllDataByCondition({ where: {tid: material.tid }}); if (this._checkFieldsExist(fields, posFields.stage)) { const curPosStage = await this.ctx.service.stagePos.getStagesData(material.tid, material.stage_id); this.ctx.helper.assignRelaData(posData, [ {data: curPosStage, fields: ['contract_qty', 'qc_qty', 'qc_minus_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 getMaterialStage(fields) { const material = this.ctx.material; 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, }]; } } async getMaterialExponent(fields) { if (!this.ctx.material) return []; const materials = await this.ctx.service.material.getAllDataByCondition({ where: {tid: this.ctx.material.tid}, orders: [['order', 'desc']], }); if (materials.length === 0) return []; let result, material; material = this.ctx.material; if (materials[0].order === material.order) { result = await this.ctx.service.materialExponent.getAllDataByCondition({ where: { tid: material.tid } }); } else { const sql = 'SELECT me.id, me.tid, me.mid, mb.type, mb.symbol, mb.symbol_desc, mb.code, mb.remark, mb.in_time,' + ' meh.type, meh.weight_num, meh.basic_price, meh.basic_times, meh.m_price, meh.calc_num, meh.is_summary' + ' FROM ' + this.ctx.service.materialExponentHistory.tableName + ' meh ' + ' LEFT JOIN ' + this.ctx.service.materialExponent.tableName + ' me ON meh.me_id = me.id ' + ' WHERE meh.tid = ? And meh.mid = ?'+ ' ORDER By me.id'; result = await this.ctx.app.mysql.query(sql, [material.tid, material.id]); } return result; } getCommonData(params, tableName, fields, customDefine, customSelect) { switch (tableName) { case 'mem_project': return this.ctx.service.project.getDataByCondition({ id: this.ctx.session.sessionProject.id }); case 'mem_tender': return [this.ctx.tender.data]; case 'mem_tender_info': return [this.ctx.tender.info]; case 'mem_deal_bills': return this.ctx.service.dealBills.getAllDataByCondition({ where: { tender_id: this.ctx.tender.id } }); case 'mem_material': return [this.ctx.material]; case 'mem_material_audit': return this.getMaterialAuditors(); case 'mem_material_gl': return this.getMaterialGl(fields); case 'mem_material_gl_detail': return this.getMaterialGlDetail(fields); case 'mem_material_bills': return this.getMaterialBills(fields); case 'mem_material_bills_filter': return this.getMaterialBills(fields, true); case 'mem_material_pos': return this.getMaterialPos(fields); case 'mem_material_stage': return this.getMaterialStage(fields); case 'mem_material_exponent': return this.getMaterialExponent(fields); default: return []; } } getMaterialCalcQty(qtySource, info, is_join) { let qty = 0; switch(qtySource) { case materialConst.qty_source_value.gather_qty: qty = info.gather_qty; break; case materialConst.qty_source_value.contract_qty: qty = info.contract_qty; break; case materialConst.qty_source_value.gather_minus_qty: qty = info.gather_minus_qty; break; default: throw '未配置计量来源'; } if (qtySource !== materialConst.qty_source_value.contract_qty && is_join === 2) { qty = info.contract_qty; } return qty; } async _getMaterialStageGatherBills(tender_id, stage_id, stage_order, stageSelf, stageIndex = 0) { const decimal = this.materialGatherBase.decimal; const billsData = this.materialGatherBase.billsData; billsData.forEach(x => { for (const prop of ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'qc_minus_qty']) { 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', 'qc_minus_qty'], prefix: '', relaId: 'lid' }, ]); const billsTree = this._getNewBillsTree(); billsTree.loadDatas(billsData); billsTree.calculateAll(); const posData = this.materialGatherBase.posData; posData.forEach(x => { for (const prop of ['contract_qty', 'qc_qty', 'qc_minus_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', 'qc_minus_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 materialNotChange = this.materialGatherBase.materialNotChange; const helper = this.ctx.helper; for (const g of gatherUtil.gclList) { if (!g.contract_qty && !g.qc_qty && !g.qc_minus_qty) continue; g.sid = stage_id; g.sorder = stage_order; g.s_index = stageIndex; g.jiacha = 0; g.jiacha_qty = 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 mnc = materialNotChange.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_change = mnc ? 2 : 1; 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; x.jiacha_qty = this.getMaterialCalcQty(this.materialGatherBase.qtySource, x, x.is_change); for (const l of list) { x.jiacha = helper.add(x.jiacha, helper.mul(helper.mul(x.jiacha_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.jiacha_qty); } } return [gatherUtil.gclList, gatherUtil.leafXmjs]; } async getMaterialGatherBills() { const material = this.ctx.material; if (!material) return {}; const materials = await this.ctx.service.material.getAllDataByCondition({ where: { tid: material.tid }, orders: [['order', 'desc']], }); if (materials.length === 0) return {}; this.materialGatherBase = {}; this.materialGatherBase.qtySource = material.qty_source; this.materialGatherBase.decimal = material.decimal ? JSON.parse(material.decimal) : materialConst.decimal; try { // 获取基础数据 this.materialGatherBase.billsData = await this.ctx.service.ledger.getData(material.tid); this.materialGatherBase.posData = await this.ctx.service.pos.getPosData({ tid: material.tid }); if (material.is_stage_self) { this.materialGatherBase.materialGl = material.order === materials[0].order ? await this.ctx.service.materialList.getMaterialStageData(material.tid, material.id) : await this.ctx.service.materialList.getPreMaterialStageData(material.tid, material.id); } else { this.materialGatherBase.materialGl = material.order === materials[0].order ? await this.ctx.service.materialList.getMaterialData(material.tid, material.id) : await this.ctx.service.materialList.getPreMaterialData(material.tid, material.id); } this.materialGatherBase.materialNotJoin = await this.ctx.service.materialListNotjoin.getAllDataByCondition({ where: { mid: material.id, type: 1 } }); this.materialGatherBase.materialNotChange = await this.ctx.service.materialListNotjoin.getAllDataByCondition({ where: { mid: material.id, type: 2 } }); 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(material.tid, 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(material.tid, 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 getBindData(params, key, fields, customDefine, customSelect) { switch (key) { case 'materialGather': return await this.getMaterialGatherBills(); default: return {}; } } } module.exports = rptMemChange;