/**
* Created by Zhong on 2017/12/21.
*/
const mongoose = require('mongoose');
const compleRationSectionTreeModel = mongoose.model('complementary_ration_section_tree');
const compleRationModel = mongoose.model('complementary_ration_items');
const installSectionModel = mongoose.model("std_ration_lib_installationSection");
const installFeeItemModel = mongoose.model("std_ration_lib_installation");
const complementaryGljModel = mongoose.model('complementary_glj_lib');
const stdGljModel = mongoose.model('std_glj_lib_gljList');
const stdgljutil = require('../../../public/cache/std_glj_type_util');
const installFacade = require('../facades/compleInstallFacade');
const async = require('async');
let stdRationModel = require ('../../ration_repository/models/ration_item').Model;
const SectionTreeDao = require('../models/sectionTreeModel');
const sectionTreeDao = new SectionTreeDao();
const GljDao = require("../../complementary_glj_lib/models/gljModel");
const gljDao = new GljDao();
let counter = require('../../../public/counter/counter');
const scMathUtil = require('../../../public/scMathUtil').getUtil();
let gljUtil = require('../../../public/gljUtil');
const { ShareLibType } = require('../../../public/common_constants');
const pmFacade = require('../../pm/facade/pm_facade');
class CompleRatoinDao {
async updateRation(userID, compilationId, updateData, callback){
try{
for(let i = 0, len = updateData.length; i < len; i++){
let updateObj = updateData[i];
if(updateObj.updateType === 'new'){
updateObj.updateData.userID = userID;
updateObj.updateData.compilationId = compilationId;
await compleRationModel.create(updateObj.updateData);
}
else if(updateObj.updateType === 'update'){
await compleRationModel.update({userID: userID, rationRepId: updateObj.updateData.rationRepId}, updateObj.updateData);
}
}
callback(0, '');
}
catch(err){
callback(err, null);
}
}
async getRationItems(sectionId, callback){
try{
let compleRations = await compleRationModel.find({sectionId: sectionId, deleteInfo: null});
callback(0, compleRations);
}
catch(err){
callback(err, null);
}
}
async getRationsCodes(userID, rationRepId, callback){
try{
let stdRationCodes = await stdRationModel.find({rationRepId: rationRepId, $or: [{isDeleted: null}, {isDeleted: false}]}, '-_id code');
let compleRationCodes = await compleRationModel.find({userId: userID, rationRepId: rationRepId, deleteInfo: null}, '-_id code');
let rstCodes = [];
stdRationCodes.concat(compleRationCodes).forEach(function (rationItem) {
rstCodes.push(rationItem.code);
});
callback(0, rstCodes);
}
catch(err){
callback(err, null);
}
}
async getGljItems(gljLibId, callback){
try{
let stdGljs = await stdGljModel.find({repositoryId: gljLibId, $or: [{deleted: null}, {deleted: false}]});
callback(0, stdGljs);
}
catch(err){
callback(err, null);
}
}
async getGljItemsOccupied(gljLibId, occupation, callback){
try{
let stdGls = await stdGljModel.find({repositoryId: gljLibId, $or: [{deleted: null}, {deleted: false}]}, occupation);
callback(0, stdGls);
}
catch (err){
callback(err, null);
}
}
async getGljItemsByIds(userID, ids, callback){
try{
let rst = [];
for(let i = 0, len = ids.length; i < len; i++){
if(ids[i].type === 'std'){
let stdGlj = await stdGljModel.find({ID: ids[i].id, deleteInfo: null});
if(stdGlj.length > 0){
stdGlj[0]._doc.type = 'std';
rst.push(stdGlj[0]);
}
}
else if(ids[i].type === 'complementary'){
const owner = ids[i].fromUser || userID;
let compleGlj = await complementaryGljModel.find({userId: owner, ID: ids[i].id, deleteInfo: null});
if(compleGlj.length > 0){
compleGlj[0]._doc.type = 'complementary';
rst.push(compleGlj[0]);
}
}
}
callback(0, rst);
}
catch(err){
callback(err, null);
}
}
async getGljItemsByCodes(userID, compilationId, rationRepId, codes, callback){
try{
let rst = [];
for(let i = 0, len = codes.length; i < len; i++){
let stdGlj = await stdGljModel.find({repositoryId: rationRepId, code: codes[i]});
if(stdGlj.length > 0){
stdGlj[0]._doc.type = 'std';
rst.push(stdGlj[0]);
}
else {
let compleGlj = await complementaryGljModel.find({userId: userID, compilationId: compilationId, code: codes[i]});
if(compleGlj.length > 0){
compleGlj[0]._doc.type = 'complementary';
rst.push(compleGlj[0]);
}
}
}
callback(0, rst);
}
catch(err){
callback(err, null);
}
}
//根据章节树获取补充定额
async getCompleRationBySection(userId, sectionId) {
const deleteQuery = [{deleteInfo: null}, {'deleteInfo.deleted': false}];
let compleRations = await compleRationModel.find({sectionId: sectionId, $or: deleteQuery});
for(let ration of compleRations){
ration._doc.type = 'complementary';
let hintsArr = [];
let stdGljIds = [],
comGljIds = [],
stdGljs = [],
comGljs = [];
const users = [userId];
let gljAmtMapping = {};
for(let rationGlj of ration.rationGljList){
gljAmtMapping[rationGlj.gljId] = rationGlj.consumeAmt;
if(!isDef(rationGlj.type) || rationGlj.type === 'std'){
stdGljIds.push(rationGlj.gljId);
}
else {
if (rationGlj.fromUser && !users.includes(rationGlj.fromUser)) {
users.push(rationGlj.fromUser);
}
comGljIds.push(rationGlj.gljId);
}
}
if(stdGljIds.length > 0) {
stdGljs = await stdGljModel.find({ID: {$in: stdGljIds}}).lean();
}
if(comGljIds.length > 0) {
comGljs = await complementaryGljModel.find({userId: { $in: users }, ID: {$in: comGljIds}}).lean();
}
let gljDatas = gljUtil.sortRationGLJ(stdGljs.concat(comGljs),true);
if(ration.jobContent && ration.jobContent.toString().trim() !== ''){
hintsArr.push(`");
hintsArr.push("");
}
for(let glj of gljDatas){
hintsArr.push(``)
}
hintsArr.push(`基价 元 ${ration.basePrice}`);
if(ration.annotation && ration.annotation.toString().trim() !== ''){
hintsArr.push(`
附注:`);
hintsArr = hintsArr.concat(ration.annotation.split('\n'));
}
ration._doc.hint = hintsArr.join('
');
}
return compleRations;
}
//造价书定额库 根据章节树过去标准定额
async getRationGljItemsBySection(sectionId, callback){
let stdRations = await stdRationModel.find({sectionId: sectionId});
for(let ration of stdRations){
ration._doc.type = 'std';
}
function sortByCode(arr) {
function recurCompare(a, b, index){
if (a[index] && !b[index]) {
return 1;
} else if (!a[index] && b[index]) {
return -1;
} else if (a[index] && b[index]) {
let aV = a[index],
bV = b[index];
if (!isNaN(aV) && !isNaN(bV)) {
aV = parseFloat(a[index]);
bV = parseFloat(b[index]);
}
if (aV > bV) {
return 1;
} else if (aV < bV) {
return -1;
} else {
return recurCompare(a, b, index + 1);
}
}
return 0;
}
arr.sort(function (a, b) {
let aArr = a.code.split('-'),
bArr = b.code.split('-');
return recurCompare(aArr, bArr, 0);
});
}
/*stdRations.sort(function (a, b) {
let rst = 0;
if(a.code > b.code){
rst = 1;
}
else if(a.code < b.code){
rst = -1;
}
return rst;
});*/
sortByCode(stdRations);
for(let ration of stdRations){
let hintsArr = [];
let stdGljIds = [],
stdGljs = [];
let gljAmtMapping = {};
for(let rationGlj of ration.rationGljList){
gljAmtMapping[rationGlj.gljId] = rationGlj.consumeAmt;
stdGljIds.push(rationGlj.gljId);
}
if(stdGljIds.length > 0) {
stdGljs = await stdGljModel.find({ID: {$in: stdGljIds}}).lean();
/*stdGljs.forEach(function (glj) {
glj.type = glj.gljType;
});*/
}
let gljDatas = gljUtil.sortRationGLJ(stdGljs,true);
if(ration.jobContent && ration.jobContent.toString().trim() !== ''){
hintsArr.push(`");
hintsArr.push("");
}
for(let glj of gljDatas){
hintsArr.push(``)
}
hintsArr.push(`基价 元 ${ration.basePrice}`);
if(ration.annotation && ration.annotation.toString().trim() !== ''){
hintsArr.push(`
附注:`);
hintsArr = hintsArr.concat(ration.annotation.split('\n'));
}
ration._doc.hint = hintsArr.join('
');
}
return stdRations;
}
updateRationBasePrc(userID, basePrcArr, callback){
let me = this;
async.each(basePrcArr, function (basePrcObj, finalCb) {
let adjGljId = basePrcObj.gljId, adjBasePrice = basePrcObj.basePrice, adjGljType = basePrcObj.gljType;
async.waterfall([
function (cb) {
if(typeof basePrcObj.delete !== 'undefined' && basePrcObj.delete === 1){
//补充定额
compleRationModel.find({'rationGljList.gljId': adjGljId},{ID: 1, rationGljList: 1}, function (err, compleRst) {
if(err){
cb(err);
}
else {
compleRationModel.update({'rationGljList.gljId': adjGljId}, {$pull: {rationGljList: {gljId: adjGljId}}}, {multi: true}, function (err) {
if(err){
cb(err);
}
else {
cb(null, compleRst);
}
});
}
});
}
else{
compleRationModel.find({'rationGljList.gljId': adjGljId}, function (err, compleRst) {
if(err){
cb(err);
}
else {
cb(null, compleRst);
}
});
}
},
function (result, cb) {
async.each(result, function (rationItem, ecb) {
let rationGljList = rationItem.rationGljList,
gljIds = [];
rationGljList.forEach(function (rationGlj) {
let idObj = Object.create(null);
idObj.id = rationGlj.gljId;
idObj.type = rationGlj.type;
gljIds.push(idObj);
});
me.getGljItemsByIds(userID, gljIds, function(err, gljItems){
if(err){
ecb(err);
}
else{
let gljArr = [];
for(let i=0; i 200 && gljItems[i].gljType < 300){
gljParentType = 2;
}
if(gljItems[i].gljType > 300 && gljItems[i].gljType < 400){
gljParentType = 3;
}
if(gljItems[i].ID === adjGljId){
gljArr.push({gljId: gljItems[i].ID, basePrice: adjBasePrice, gljParentType: gljParentType});
}
else {
gljArr.push({gljId: gljItems[i].ID, basePrice: parseFloat(gljItems[i].basePrice), gljParentType: gljParentType});
}
}
gljArr.forEach(function (gljItem) {
rationGljList.forEach(function (rationGlj) {
if(gljItem.gljId === rationGlj.gljId){
gljItem.consumeAmt = parseFloat(rationGlj.consumeAmt);
}
})
});
//recalculate the price of ration
let labourPrc = [], materialPrc = [], machinePrc = [], singlePrc, updatePrc = {labourPrice: 0, materialPrice: 0, machinePrice: 0, basePrice: 0};
gljArr.forEach(function (gljItem) {
if(gljItem.gljParentType !== -1){
singlePrc = scMathUtil.roundTo(gljItem.basePrice * gljItem.consumeAmt, -3);
if(gljItem.gljParentType === 1){
labourPrc.push(singlePrc);
}
else if(gljItem.gljParentType ===2){
materialPrc.push(singlePrc);
}
else{
machinePrc.push(singlePrc);
}
}
});
if(labourPrc.length > 0){
let sumLaP = 0;
for(let i=0; i 0){
let sumMtP = 0;
for(let i= 0; i 0){
let sumMaP = 0;
for(let i =0; i< machinePrc.length; i++){
sumMaP += machinePrc[i];
}
updatePrc.machinePrice = scMathUtil.roundTo(sumMaP, -2);
}
updatePrc.basePrice = scMathUtil.roundTo(updatePrc.labourPrice + updatePrc.materialPrice + updatePrc.machinePrice, -2);
//updateDataBase
compleRationModel.update({ID: rationItem.ID}, {$set: {labourPrice: updatePrc.labourPrice.toString(), materialPrice: updatePrc.materialPrice.toString(),
machinePrice: updatePrc.machinePrice.toString(), basePrice: updatePrc.basePrice.toString()}},
function (err, result) {
if(err){
ecb(err);
}
else {
ecb(null);
}
});
}
});
}, function(err){
if(err){
cb(err);
}
else {
cb(null);
}
});
},
], function (err) {
if(err){
finalCb(err);
}
else{
finalCb(null);
}
});
}, function (err) {
if(err){
callback(err, 'Error');
}
else{
callback(0, '');
}
});
}
mixUpdateRationItems (userID, compilationId, rationLibId, sectionId, updateItems, addItems, rIds, callback){
let me = this;
if (updateItems.length == 0 && rIds.length == 0) {
me.addRationItems(userID, compilationId, rationLibId, sectionId, addItems, callback);
} else {
me.removeRationItems(rationLibId, rIds, function(err, message, docs) {
if (err) {
callback(true, false);
} else {
me.updateRationItems(userID, rationLibId, sectionId, updateItems, function(err, results){
if (err) {
callback(true, false);
} else {
if (addItems && addItems.length > 0) {
me.addRationItems(rationLibId, sectionId, addItems, callback);
} else {
callback(0, results);
}
}
});
}
})
}
}
removeRationItems(rationRepId, rIds,callback){
if (rIds.length > 0) {
compleRationModel.remove({rationRepId: rationRepId, ID: {$in: rIds}}, function(err, docs){
if (err) {
callback(true, false);
} else {
callback(0, docs);
}
})
} else {
callback(0, null);
}
}
addRationItems(userID, compilationId, rationLibId, sectionId, items,callback){
if (items && items.length > 0) {
counter.counterDAO.getIDAfterCount(counter.moduleName.rations, items.length, function(err, result){
let maxId = result.sequence_value;
let arr = [];
for (let i = 0; i < items.length; i++) {
let obj = new compleRationModel(items[i]);
obj.ID = (maxId - (items.length - 1) + i);
obj.sectionId = sectionId;
obj.rationRepId = rationLibId;
obj.userId = userID;
obj.compilationId = compilationId;
arr.push(obj);
}
compleRationModel.collection.insert(arr, null, function(err, docs){
if (err) {
callback(true, false);
} else {
callback(0, docs);
}
})
});
} else {
callback(true, "Source error!", false);
}
}
updateRationItems(userID, rationLibId, sectionId, items,callback){
let functions = [];
for (let i=0; i < items.length; i++) {
functions.push((function(doc) {
return function(cb) {
var filter = {};
if (doc.ID) {
filter.ID = doc.ID;
} else {
filter.sectionId = sectionId;
filter.userId = userID;
if (rationLibId) filter.rationRepId = rationLibId;
filter.code = doc.code;
}
compleRationModel.update(filter, doc, cb);
};
})(items[i]));
}
async.parallel(functions, function(err, results) {
if(!err){
err = 0;
}
callback(err, results);
});
}
async getCodes (userId, compilationId) {
const compleRations = await compleRationModel.find({userId, compilationId}, '-_id code').lean();
const codes = [];
compleRations.forEach(item => codes.push(item.code));
return codes;
}
async prepareInitData (sessionUserID, userId, compilationId, gljLibId) {
const receiveLibs = await pmFacade.getReceiveLibList(sessionUserID, compilationId, ShareLibType.RATION_LIB);
const shareLibs = sessionUserID === userId ? await pmFacade.getLibShareList(sessionUserID, compilationId, ShareLibType.RATION_LIB) : [];
const rationsCodes = await this.getCodes(userId, compilationId);
const gljDistTypeCache = stdgljutil.getStdGljTypeCacheObj().toArray();
const installationData = await installFacade.getInstallation(userId, compilationId);
const rationTreeData = await sectionTreeDao.getComplementaryTree(userId, compilationId);
const mixedTreeData = await gljDao.getMixedTree(gljLibId, userId, compilationId);
const mixedGLJData = await gljDao.getGLJDataSync(gljLibId, userId, compilationId);
return {
shareLibs,
receiveLibs,
rationsCodes,
gljDistTypeCache,
installationData,
rationTreeData,
mixedTreeData,
mixedGLJData
}
}
}
function isDef(v){
return v !== undefined && v !== null;
}
module.exports = CompleRatoinDao;