123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- /**
- * Created by CSL on 2017-07-19.
- * dispExpr: F8*(L-1); expression: "@('8') * (L-1)";
- * 说明:F后跟行号,L替换人工系数值,@后跟ID。用到L的规则必须有labourCoeID属性(反过来不要求),
- * 用到费率的规则必须有feeRateID属性,当有该属性时,会自动显示费率值。
- */
- let defaultBillTemplate = [
- {
- ID: 1,
- serialNo: '一',
- code: "A",
- name: "定额直接费",
- dispExpr: "A1+A2+A3",
- statement: "人工费+材料费+机械费",
- feeRate: null,
- memo: ''
- },
- {
- ID: 2,
- serialNo: '1',
- code: "A1",
- name: "人工费",
- dispExpr: "HJ",
- statement: "合计",
- feeRate: 50,
- fieldName: 'labour',
- memo: ''
- },
- {
- ID: 3,
- serialNo: '2',
- code: "A2",
- name: "材料费",
- dispExpr: "HJ",
- statement: "合计",
- feeRate: 30,
- fieldName: 'material',
- memo: ''
- },
- {
- ID: 4,
- serialNo: '3',
- code: "A3",
- name: "机械费",
- dispExpr: "HJ",
- statement: "合计",
- feeRate: 20,
- fieldName: 'machine',
- memo: ''
- },
- {
- ID: 5,
- serialNo: '二',
- code: "A4",
- name: "管理费",
- dispExpr: "A",
- statement: "定额直接费",
- feeRate: null,
- fieldName: 'manage',
- memo: ''
- },
- {
- ID: 6,
- serialNo: '三',
- code: "B",
- name: "利润",
- dispExpr: "A",
- statement: "定额直接费",
- feeRate: null,
- fieldName: 'profit',
- memo: ''
- },
- {
- ID: 7,
- serialNo: '四',
- code: "C",
- name: "风险费用",
- dispExpr: "",
- statement: "",
- feeRate: null,
- fieldName: 'risk',
- memo: ''
- },
- {
- ID: 8,
- serialNo: '',
- code: "",
- name: "综合单价",
- dispExpr: "A+B",
- statement: "定额直接费+利润",
- feeRate: null,
- fieldName: 'common',
- memo: ''
- }
- ];
- class CalcProgram {
- constructor(project){
- this.project = project;
- this.datas = [];
- this.digit = 2;
- this.digitDefault = 6;
- this.calc = new Calculation();
- project.registerModule(ModuleNames.calc_program, this);
- };
- getSourceType () {
- return ModuleNames.calc_program;
- };
- loadData (datas) {
- this.datas = datas;
- };
- doAfterUpdate (err, data) {
- if(!err){
- // do
- }
- };
- // 经测试,全部编译一次耗时0.003~0.004秒。耗时基本忽略不计。
- compileAllTemps(){
- let calcFeeRates = this.project.FeeRate.datas.rates;
- let calcLabourCoes = this.project.labourCoe.datas.coes;
- let calcTemplates = this.project.calcProgram.datas.templates;
- this.calc.compilePublics(calcFeeRates, calcLabourCoes, feeType, rationCalcBase);
- for (let ct of calcTemplates){
- this.calc.compileTemplate(ct);
- };
- // 存储费率临时数据,报表用。
- if (this.calc.saveForReports.length > 0){
- let saveDatas = {};
- saveDatas.projectID = projectInfoObj.projectInfo.ID;
- saveDatas.calcItems = this.calc.saveForReports;
- CommonAjax.post('/calcProgram/saveCalcItems', saveDatas, function (data) {
- this.calc.saveForReports = [];
- });
- };
- };
- calculate(treeNode){
- let me = this;
- if (treeNode.sourceType === this.project.Ration.getSourceType()) {
- treeNode.data.gljList = this.project.ration_glj.getGljArrByRation(treeNode.data.ID);
- }
- else if (treeNode.sourceType === this.project.Bills.getSourceType()) {
- let rations = this.project.Ration.getBillsSortRation(treeNode.source.getID());
- treeNode.data.gljList = this.project.ration_glj.getGatherGljArrByRations(rations);
- };
- this.calc.calculate(treeNode);
- // 存储、刷新本结点、所有父结点
- if (treeNode.changed) {
- me.saveAndCalcParents(treeNode);
- delete treeNode.changed;
- };
- };
- saveAndCalcParents(treeNode) {
- if (treeNode.parent) {
- projectObj.converseCalculateBills(treeNode.parent);
- };
- let data = {ID: treeNode.data.ID, projectID: projectObj.project.ID(), fees: treeNode.data.fees};
- let newDta = {'updateType': 'ut_update', 'updateData': data};
- let newDataArr = [];
- newDataArr.push(newDta);
- projectObj.project.pushNow('', treeNode.sourceType, newDataArr);
- projectObj.mainController.refreshTreeNode([treeNode]);
- };
- initFees(treeNode){
- if (!treeNode.data.fees) {
- treeNode.data.fees = [];
- treeNode.data.feesIndex = {};
- treeNode.changed = true;
- };
- };
- checkFee(treeNode, ftObj){
- if (!treeNode.data.feesIndex[ftObj.fieldName]){
- let fee = {
- 'fieldName': ftObj.fieldName,
- 'unitFee': ftObj.unitFee,
- 'totalFee': ftObj.totalFee,
- 'tenderUnitFee': 0,
- 'tenderTotalFee': 0
- };
- treeNode.data.fees.push(fee);
- treeNode.data.feesIndex[ftObj.fieldName] = fee;
- treeNode.changed = true;
- }
- else{
- if (treeNode.data.feesIndex[ftObj.fieldName].unitFee != ftObj.unitFee){
- treeNode.data.feesIndex[ftObj.fieldName].unitFee = ftObj.unitFee;
- treeNode.changed = true;
- };
- if (treeNode.data.feesIndex[ftObj.fieldName].totalFee != ftObj.totalFee){
- treeNode.data.feesIndex[ftObj.fieldName].totalFee = ftObj.totalFee;
- treeNode.changed = true;
- };
- };
- };
- gatherFeeTypes(treeNode, gatherType){
- let me = this;
- let rst = [];
- if (treeNode.sourceType === this.project.Bills.getSourceType()) {
- me.initFees(treeNode);
- let objsArr = [];
- if (gatherType == CP_GatherType.rations){
- objsArr = this.project.Ration.getRationsByNode(treeNode);
- }else if (gatherType == CP_GatherType.bills){
- objsArr = treeNode.children;
- };
- for (let ft of feeType) {
- let ftObj = {};
- ftObj.fieldName = ft.type;
- ftObj.name = ft.name;
- let uf = 0, tf = 0, tuf = 0, ttf = 0;
- for (let item of objsArr) {
- let data = {};
- if (gatherType == CP_GatherType.rations){
- data = item;
- }else if (gatherType == CP_GatherType.bills){
- data = item.data;
- };
- if (data.feesIndex && data.feesIndex[ft.type]) {
- uf = (uf + parseFloat(data.feesIndex[ft.type].unitFee)).toDecimal(me.digitDefault);
- tf = (tf + parseFloat(data.feesIndex[ft.type].totalFee)).toDecimal(me.digitDefault);
- tuf = (tuf + parseFloat(data.feesIndex[ft.type].tenderUnitFee)).toDecimal(me.digitDefault);
- ttf = (ttf + parseFloat(data.feesIndex[ft.type].tenderTotalFee)).toDecimal(me.digitDefault);
- };
- };
- ftObj.unitFee = uf.toDecimal(me.digit);
- ftObj.totalFee = tf.toDecimal(me.digit);
- ftObj.tenderUnitFee = tuf.toDecimal(me.digit);
- ftObj.tenderTotalFee = ttf.toDecimal(me.digit);
- me.checkFee(treeNode, ftObj);
- rst.push(ftObj);
- };
- if (treeNode.changed) {
- me.saveAndCalcParents(treeNode);
- delete treeNode.changed;
- };
- };
- return rst;
- };
- calcDefaultBillTemp(treeNode, totalPrice){
- let me = this;
- let rst = [];
- if (treeNode.sourceType != this.project.Bills.getSourceType()){return rst};
- me.initFees(treeNode);
- for (let item of defaultBillTemplate) {
- let num = totalPrice;
- item.dispExprUser = item.dispExpr;
- item.displayFieldName = me.calc.compiledFeeTypes[item.fieldName];
- if (item.feeRate)
- item.unitFee = (totalPrice * item.feeRate * 0.01).toDecimal(me.digit)
- else
- item.unitFee = 0;
- let quantity = treeNode.data.quantity;
- if (!quantity) quantity = 0;
- item.totalFee = (item.unitFee * quantity).toDecimal(me.digit);
- item.tenderUnitFee = 0;
- item.tenderTotalFee = 0;
- me.checkFee(treeNode, item);
- };
- if (treeNode.changed) {
- me.saveAndCalcParents(treeNode);
- delete treeNode.changed;
- };
- rst = defaultBillTemplate;
- return rst;
- };
- getCalcDatas(treeNode){
- let me = this;
- let rst = [];
- let isRation = treeNode.sourceType === me.project.Ration.getSourceType();
- let isBill = treeNode.sourceType === me.project.Bills.getSourceType();
- let isLeafBill = isBill && treeNode.source.children && treeNode.source.children.length === 0;
- let isBillPriceCalc = me.project.projSetting.billsCalcMode === billsPrice;
- if (isRation) { // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。
- me.calculate(treeNode);
- rst = treeNode.data.calcTemplate.calcItems;
- }
- else if (isLeafBill) {
- let ct = '';
- if (treeNode.children && treeNode.children.length > 0){
- if (treeNode.children[0].sourceType == me.project.Ration.getSourceType()){
- ct = childrenType.ration;
- }
- else if (treeNode.children[0].sourceType == me.project.VolumePrice.getSourceType()){
- ct = childrenType.volumePrice;
- };
- }
- else{
- ct = childrenType.formula;
- };
- if (ct == childrenType.ration){
- if (isBillPriceCalc){ // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。
- me.calculate(treeNode);
- rst = treeNode.data.calcTemplate.calcItems;
- }else{ // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
- rst = me.gatherFeeTypes(treeNode, CP_GatherType.rations);
- };
- }
- else if (ct == childrenType.volumePrice){
- let totalPrice = 10000;
- rst = me.calcDefaultBillTemp(treeNode, totalPrice);
- }
- else if (ct == childrenType.formula){
- let totalPrice = 20000;
- rst = me.calcDefaultBillTemp(treeNode, totalPrice);
- };
- }
- else if (isBill){ // 父清单:汇总子清单的费用类别
- rst = me.gatherFeeTypes(treeNode, CP_GatherType.bills);
- };
- return rst;
- }
- }
|