|
@@ -42,7 +42,8 @@ module.exports = {
|
|
|
editBillMaterials,
|
|
|
generateClassData,
|
|
|
getClassExcelData,
|
|
|
- testItems
|
|
|
+ autoSetMaterial,
|
|
|
+ testItems,
|
|
|
};
|
|
|
|
|
|
function setChildren(bill, parentMap) {
|
|
@@ -915,7 +916,6 @@ function combineData(codeData, requireRationData, optionalRationData, classGroup
|
|
|
return { itemClassData: finData, unMatchRation };
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// 生成清单分类
|
|
|
async function generateClassData(libID) {
|
|
|
const lib = await billsGuideLibModel.findOne({ ID: libID }).lean();
|
|
@@ -1099,4 +1099,157 @@ async function testItems(libID) {
|
|
|
|
|
|
}*/
|
|
|
return delBulk.length;
|
|
|
+}
|
|
|
+
|
|
|
+// 获取清单ID - 指引数据映射
|
|
|
+async function getGuidanceMap(libID) {
|
|
|
+ const guidanceItems = await billsGuideItemsModel.find({ libID }, '-_id').lean();
|
|
|
+ // 清单ID - 指引数据映射
|
|
|
+ const guidanceMap = {};
|
|
|
+ guidanceItems.forEach(item => {
|
|
|
+ (guidanceMap[item.billsID] || (guidanceMap[item.billsID] = [])).push(item);
|
|
|
+ });
|
|
|
+ return guidanceMap;
|
|
|
+}
|
|
|
+
|
|
|
+// 获取清单树
|
|
|
+async function getBillTree(libID) {
|
|
|
+ const lib = await billsGuideLibModel.findOne({ ID: libID }).lean();
|
|
|
+ if (!lib) {
|
|
|
+ throw new Error('无有效精灵库');
|
|
|
+ }
|
|
|
+ const bills = await stdBillsModel.find({ billsLibId: lib.billsLibId }, '-_id ID ParentID NextSiblingID name code unit').lean();
|
|
|
+ const billTree = idTree.createNew({ id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true });
|
|
|
+ billTree.loadDatas(bills);
|
|
|
+ return billTree;
|
|
|
+}
|
|
|
+
|
|
|
+// 获取定额ID - 人材机数组 映射
|
|
|
+async function getRationIDGljMap(rationIDs) {
|
|
|
+ let allGljList = [];
|
|
|
+ const rations = await stdRationModel.find({ ID: { $in: rationIDs } }, '-_id ID rationGljList');
|
|
|
+ const gljIDs = [];
|
|
|
+ rations.forEach(ration => {
|
|
|
+ if (ration.rationGljList && ration.rationGljList.length) {
|
|
|
+ gljIDs.push(...ration.rationGljList.map(rGlj => rGlj.gljId));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (gljIDs.length) {
|
|
|
+ allGljList = await gljModel.find({ ID: { $in: [...new Set(gljIDs)] } }, '-_id ID code name specs gljType').lean();
|
|
|
+ }
|
|
|
+ const gljMap = {};
|
|
|
+ allGljList.forEach(glj => gljMap[glj.ID] = glj);
|
|
|
+ const rationIDGljMap = {};
|
|
|
+ rations.forEach(ration => {
|
|
|
+ if (ration.rationGljList && ration.rationGljList.length) {
|
|
|
+ rationIDGljMap[ration.ID] = ration.rationGljList.map(rGlj => gljMap[rGlj.gljId]);
|
|
|
+ } else {
|
|
|
+ rationIDGljMap[ration.ID] = [];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return rationIDGljMap;
|
|
|
+}
|
|
|
+
|
|
|
+// 需要自动配置材料的工序行
|
|
|
+function needAutoMaterialNode(node) {
|
|
|
+ const needAutoNames = [
|
|
|
+ '水泥强度等级',
|
|
|
+ '混凝土强度等级',
|
|
|
+ '砂浆强度等级',
|
|
|
+ '砌筑砂浆强度等级',
|
|
|
+ '砂浆配合比',
|
|
|
+ '砂强度等级',
|
|
|
+ '构件混凝土强度等级',
|
|
|
+ ];
|
|
|
+ const name = (node.data.name || '').trim();
|
|
|
+ return isProcessNode(node) && needAutoNames.includes(name);
|
|
|
+}
|
|
|
+
|
|
|
+// 获取需要自动配置的数据
|
|
|
+function getNeedAutoSetData(leafBills, guidanceMap) {
|
|
|
+ const allRationIDs = [];
|
|
|
+ const toAutoSetData = []; // 准备要自动配置的数据
|
|
|
+ const markMaterialIDs = []; // 需要打勾材料的数据ID
|
|
|
+ for (let billNode of leafBills) {
|
|
|
+ const guidanceItems = guidanceMap[billNode.data.ID];
|
|
|
+ if (!guidanceItems || !guidanceItems.length) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ const guidanceTree = idTree.createNew({ id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true });
|
|
|
+ guidanceTree.loadDatas(guidanceItems);
|
|
|
+ const needAutoSetItems = guidanceTree.items.filter(node => needAutoMaterialNode(node));
|
|
|
+ // 存在需要自动配置材料
|
|
|
+ if (needAutoSetItems.length) {
|
|
|
+ const rationIDs = guidanceTree.items
|
|
|
+ .filter(node => node.data.rationID)
|
|
|
+ .map(node => node.data.rationID);
|
|
|
+ allRationIDs.push(...rationIDs);
|
|
|
+ markMaterialIDs.push(...needAutoSetItems.map(node => node.data.ID));
|
|
|
+ toAutoSetData.push({
|
|
|
+ rationIDs, // 选择的材料只能从当前定额人材机下选
|
|
|
+ billID: billNode.data.ID,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return { allRationIDs, markMaterialIDs, toAutoSetData };
|
|
|
+}
|
|
|
+
|
|
|
+const autoSetGljCodes = [
|
|
|
+ '0401',
|
|
|
+ '8001',
|
|
|
+ '8003',
|
|
|
+ '8005',
|
|
|
+ '8009',
|
|
|
+ '8011',
|
|
|
+ '8013',
|
|
|
+ '8015',
|
|
|
+ '8017',
|
|
|
+ '8019',
|
|
|
+ '8021',
|
|
|
+]
|
|
|
+
|
|
|
+// 自动配置材料
|
|
|
+async function autoSetMaterial(libID) {
|
|
|
+ const billTree = await getBillTree(libID);
|
|
|
+ const guidanceMap = await getGuidanceMap(libID);
|
|
|
+ const leafBills = billTree.items.filter(node => !node.children || !node.children.length);
|
|
|
+ const { allRationIDs, markMaterialIDs, toAutoSetData } = getNeedAutoSetData(leafBills, guidanceMap);
|
|
|
+ if (!toAutoSetData.length) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const rationIDGljMap = await getRationIDGljMap([...new Set(allRationIDs)]);
|
|
|
+ const billMaterials = []; // 自动配置材料 (如果原本有配置,则替换原本的:删除旧的doc,插入新的doc)
|
|
|
+ const billIDs = [];
|
|
|
+ toAutoSetData.forEach(({ billID, rationIDs }) => {
|
|
|
+ billIDs.push(billID);
|
|
|
+ // 清单工料机
|
|
|
+ const billGljList = rationIDs.reduce((list, cur) => {
|
|
|
+ if (rationIDGljMap[cur]) {
|
|
|
+ list.push(...rationIDGljMap[cur])
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }, []);
|
|
|
+ // 从清单工料机列表中筛选,当前清单下定额工料机中存在的,配置到“配置材料”中,需要命中材料编码前四位
|
|
|
+ const materialIDs = [];
|
|
|
+ billGljList.forEach(glj => {
|
|
|
+ const fourCode = (glj.code || '').substr(0, 4);
|
|
|
+ if (autoSetGljCodes.includes(fourCode) && !materialIDs.includes(glj.ID)) {
|
|
|
+ materialIDs.push(glj.ID);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const materials = materialIDs.map(gljID => ({ gljID }));
|
|
|
+ billMaterials.push({
|
|
|
+ libID,
|
|
|
+ billID,
|
|
|
+ ID: uuidV1(),
|
|
|
+ materials
|
|
|
+ });
|
|
|
+ });
|
|
|
+ // 打勾材料
|
|
|
+ await billsGuideItemsModel.updateMany({ ID: { $in: markMaterialIDs } }, { $set: { isMaterial: true } });
|
|
|
+ // 删除要被替换的清单材料
|
|
|
+ await billMaterialModel.deleteMany({ libID, billID: { $in: billIDs } });
|
|
|
+ // 插入新的材料
|
|
|
+ await billMaterialModel.insertMany(billMaterials);
|
|
|
}
|