/** * 单价业务模型 * * @author CaiAoLin * @date 2017/6/30 * @version */ import BaseModel from "../../common/base/base_model" import GLJTypeConst from "../../common/const/glj_type_const" import CounterModel from "./counter_model" import MixRatioModel from "./mix_ratio_model"; import {default as UnitPriceSchema, collectionName as collectionName} from "./schemas/unit_price"; import _ from "lodash"; const scMathUtil = require('../../../public/scMathUtil').getUtil(); class UnitPriceModel extends BaseModel { /** * 构造函数 * * @return {void} */ constructor() { let parent = super(); parent.model = UnitPriceSchema; parent.init(); } /** * 根据单价文件id获取单价数据 * * @param {Number} fileId * @return {Promise} */ async getDataByFileId(fileId) { fileId = parseInt(fileId); if (isNaN(fileId) || fileId <= 0) { return null; } let unitPriceList = await this.db.model.find({unit_price_file_id: fileId}); if (unitPriceList.length <= 0) { return null; } // 整理数据 let result = {}; for(let tmp of unitPriceList) { let index = this.getIndex(tmp,['code','name','specs','unit','type']) result[index] = tmp; } return result; } /** * 设置场景 * * @param {string} scene * @return {void} */ setScene(scene = '') { switch (scene) { // 新增数据的验证规则 case 'add': this.model.schema.path('base_price').required(true); this.model.schema.path('market_price').required(true); this.model.schema.path('name').required(true); this.model.schema.path('code').required(true); // this.model.schema.path('unit').required(true); this.model.schema.path('type').required(true); this.model.schema.path('unit_price_file_id').required(true); } } /** * 新增单价数据 * * @param {Object} data * @param {Number} unitPriceFileId * @param {Number} gljCount * @return {Promise} 返回数据以及是否新增 */ async addUnitPrice(data, unitPriceFileId,operation='add', gljCount = 0) { if (data.original_code===undefined||data.code === undefined || data.project_id === undefined || data.name === undefined || data.market_price === undefined) { return [null, false]; } // 先查找是否有原始code相同的记录 let unitPriceData = await this.findDataByCondition({original_code: data.original_code, unit_price_file_id: unitPriceFileId}, null, false); // 如果有记录,判断是否存在一样的名称,单位...等,有则直接返回数据 let unitPrice=null; if(operation=='add'){//新增操作时,要把code也一起判断,是否完全一样 unitPrice = this.isPropertyInclude(unitPriceData,['code','name','specs','unit','type'],data); }else {//修改操作时,code不用加入判断,因为code是需要改变的 unitPrice = this.isPropertyInclude(unitPriceData,['name','specs','unit','type'],data); } if(unitPrice){ return [unitPrice, false]; } // 如果不存在基价单价,则在数据源中获取 if (data.base_price === undefined) { let firstUnitPrice = unitPriceData[0] !== undefined ? unitPriceData[0] : []; data.base_price = firstUnitPrice.base_price !== undefined ? firstUnitPrice.base_price : 0; data.type = firstUnitPrice.type !== undefined ? firstUnitPrice.type : 0; } let insertData = { code: data.code, base_price: data.base_price, market_price: data.market_price, unit_price_file_id: unitPriceFileId, name: data.name, specs:data.specs, original_code:data.original_code, unit:data.unit, type: data.type, short_name: data.shortName !== undefined ? data.shortName : '', glj_id: data.glj_id, is_add:0 }; if(data.from=='cpt'){//如果是来自补充工料机,则都添加新增标记 insertData.is_add=1; }else if (unitPriceData&&unitPriceData.length>0) {// 如果原始编码能找到,但不存在一样的编号,名称,单位.型号等,更改code和添加新增标记 insertData.code = data.original_code+"-"+unitPriceData.length; insertData.is_add=1; } let addPriceResult = await this.add(insertData); return [addPriceResult, true]; } /** * 新增记录 * * @param {object} data * @return {Promise} */ async add(data) { let counterModel = new CounterModel(); if (data instanceof Array) { // 如果是批量新增 for(let tmp in data) { data[tmp].id = await counterModel.getId(collectionName); } } else { data.id = await counterModel.getId(collectionName); } this.setScene('add'); return this.db.model.create(data); } /** * 判断数据中是否包含某个市场价格的记录 * * @param {Array} data * @param {Number} price * @return {Number} */ isPriceIncluded(data, price) { let index = -1; if (data.length <= 0) { return index; } for(let tmp in data) { if (data[tmp].market_price === price) { index = tmp; break; } } return index; } isPropertyInclude(data,pops,obj){ let condition={}; if (data.length <= 0) { return null; } if(pops instanceof Array){ for(let p of pops){ if(obj[p]){ condition[p]=obj[p] } } }else { condition[pops]=obj[pops] } return _.find(data,condition); } /** * 更新市场单价 * * @param {Object} condition * @param {Object} updateData * @param {String} extend * @return {Promise} */ async updatePrice(condition, updateData, extend = '') { if (Object.keys(condition).length <= 0 || Object.keys(updateData).length <= 0) { return false; } // 首先查找相应的数据判断工料机类型 let unitPriceData = await this.findDataByCondition(condition); if (!unitPriceData) { throw '找不到对应的单价数据'; } /* // 基价单价的计算-----先不考虑同步 switch (unitPriceData.type) { // 主材、设备自动赋值基价单价=市场单价 case GLJTypeConst.MAIN_MATERIAL: case GLJTypeConst.EQUIPMENT: updateData.base_price = updateData.market_price; break; }*/ // 额外更新数据 if (extend !== '') { extend = JSON.parse(extend); for (let code in extend) { let extendUpdateData = { market_price: extend[code].market_price, }; let tmpCondition = { unit_price_file_id: unitPriceData.unit_price_file_id, code: code }; let extendResult = await this.db.update(tmpCondition, extendUpdateData); if (!extendResult) { throw '更新额外数据,编码为' + code + '的数据失败!'; } } } let result = await this.db.update(condition, updateData); return result.ok !== undefined && result.ok === 1; } async updateUnitPrice(data){ //查找并更新单价 let doc={}; doc[data.field]=data.newval; let unitPrice = await this.db.findAndModify({id:data.id},doc); if(!unitPrice){ throw "没有找到对应的单价"; } //查找是否是属于某个项目工料机的组成物 let mixRatioModel = new MixRatioModel(); let condition = {unit_price_file_id:unitPrice.unit_price_file_id, code:unitPrice.code,name: unitPrice.name, specs: unitPrice.specs,unit:unitPrice.unit,type:unitPrice.type}; let mixRatioList = await mixRatioModel.findDataByCondition(condition, null, false); let connectKeyMap={}; //找到则计算项目工料机组成物的价格并更新 let rList= []; if(mixRatioList&&mixRatioList.length>0){ for(let m of mixRatioList){ if(!connectKeyMap.hasOwnProperty(m.connect_key)){//为了去重复,组成物会与其它项目同步,所以有可能重复。 rList.push(await this.updateParentUnitPrice(m,data.field)); connectKeyMap[m.connect_key]=true; } } } return rList; } async updateParentUnitPrice(mixRatio,fieid){ //查找该工料机所有组成物 let indexList = ['code','name','specs','unit','type']; let mixRatioModel = new MixRatioModel(); let mixRatioMap = await mixRatioModel.findDataByCondition({unit_price_file_id:mixRatio.unit_price_file_id,connect_key:mixRatio.connect_key}, null, false,indexList); //查找对应的价格 let codeList = []; let nameList = []; let specsList= []; let typeList = []; let unitList = []; for(let mk in mixRatioMap){ codeList.push(mixRatioMap[mk].code); nameList.push(mixRatioMap[mk].name); specsList.push(mixRatioMap[mk].specs); typeList.push(mixRatioMap[mk].type); unitList.push(mixRatioMap[mk].unit); } let condition = {unit_price_file_id: mixRatio.unit_price_file_id,code: {"$in": codeList}, name: {"$in": nameList},specs:{"$in": specsList},type:{"$in": typeList},unit:{"$in": unitList}}; let priceMap = await this.findDataByCondition(condition, {_id: 0}, false, indexList); let sumPrice=0; for(let pk in priceMap){ let price = parseFloat(priceMap[pk][fieid]); let consumption = parseFloat(mixRatioMap[pk].consumption); sumPrice +=scMathUtil.roundTo(price*consumption,-6); } sumPrice= scMathUtil.roundTo(sumPrice,-6); if(sumPrice<=0){ return null; } //更新父价格 let keyList = mixRatio.connect_key.split("|-|"); let pcondition = { unit_price_file_id:mixRatio.unit_price_file_id, code:keyList[0] }; for(let i = 1;i= 0) { continue; } codeList.push(tmp.code); if(nameList.indexOf(tmp.name)>=0){ continue } nameList.push(tmp.name); } // 查找即将更替的单价文件是否存在对应的工料机数据 -- (这里只根据code和名称初步过滤,因为其它的几项更改的概率不大,在下一步的比较中再精确匹配) let condition = {unit_price_file_id: changeUnitPriceId, code: {"$in": codeList},name:{"$in": nameList}}; let targetUnitList = await this.findDataByCondition(condition, null, false, ['code','name','specs','unit','type']); // 如果没有重叠的数据则原有的数据都复制一份 let insertData = []; for (let tmp of currentUnitList) { let t_index = this.getIndex(tmp,['code','name','specs','unit','type']); if (targetUnitList !== null && targetUnitList[t_index] !== undefined) { continue; } // 删除原有id信息 delete tmp._id; delete tmp.id; tmp.unit_price_file_id = changeUnitPriceId; insertData.push(tmp); } return insertData.length > 0 ? this.add(insertData) : true; } } export default UnitPriceModel;