瀏覽代碼

材料调差功能2

laiguoran 5 年之前
父節點
當前提交
9a7bd8e703
共有 5 個文件被更改,包括 190 次插入9 次删除
  1. 14 2
      app/controller/material_controller.js
  2. 68 0
      app/lib/material_calc.js
  3. 24 2
      app/public/js/material.js
  4. 82 3
      app/service/material_bills.js
  5. 2 2
      app/view/material/info.ejs

+ 14 - 2
app/controller/material_controller.js

@@ -15,6 +15,7 @@ const tenderConst = require('../const/tender');
 const measureType = tenderConst.measureType;
 const accountGroup = require('../const/account_group').group;
 const materialConst = require('../const/material');
+const MaterialCalculator = require('../lib/material_calc');
 
 module.exports = app => {
     class MaterialController extends app.BaseController {
@@ -354,7 +355,7 @@ module.exports = app => {
                         responseData.data = await ctx.service.materialBills.add();
                         break;
                     case 'del':
-                        await ctx.service.materialBills.del(data.id);
+                        responseData.data.m_tp = await ctx.service.materialBills.del(data.id);
                         break;
                     case 'update':
                         if (data.updateData.code === '' || data.updateData.code === null) {
@@ -372,7 +373,7 @@ module.exports = app => {
                         if (billData.length > 1 || (billData.length > 0 && billData[0].id !== data.updateData.id)) {
                             throw '该编号已存在,请重新输入。';
                         }
-                        await ctx.service.materialBills.save(data.updateData);
+                        responseData.data.m_tp = await ctx.service.materialBills.save(data.updateData);
                         break;
                     case 'rate':
                         // 判断数量是否为数字
@@ -384,6 +385,17 @@ module.exports = app => {
                         }
                         await ctx.service.material.changeRate(data.rate);
                         break;
+                    case 'expr':
+                        const materialCalculator = new MaterialCalculator(ctx, ctx.material.stage_id, ctx.tender.info);
+                        const quantity = await materialCalculator.calculateExpr(data.expr);
+                        // 更新quantity值并重新返回计算本期金额,截止本期金额
+                        const updateData = {
+                            id: data.id,
+                            quantity: quantity !== 0 ? quantity : null,
+                            expr: data.expr,
+                        };
+                        responseData.data = await ctx.service.materialBills.updateFYQuantity(updateData);
+                        break;
                     default: throw '参数有误';
                 }
 

+ 68 - 0
app/lib/material_calc.js

@@ -0,0 +1,68 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+const math = require('mathjs');
+
+class MaterialCalculate {
+    constructor(ctx, stage_id_list, tenderInfo) {
+        this.ctx = ctx;
+        this.stageList = stage_id_list;
+        this.percentReg = /[0-9]+%/g;
+        this.tenderInfo = tenderInfo;
+    }
+
+    /**
+     * 获取 计算基数
+     * @returns {Promise<void>}
+     */
+    async getCalcBase() {
+        if (this.bases) { return; }
+        const stage_list = await this.ctx.service.stage.getStageMsgByStageId(this.stageList);
+        const bases = await this.ctx.service.stage.getMaterialCalcBase(stage_list, this.tenderInfo);
+        this.bases = bases.sort(function(a, b) {
+            return a.sort - b.sort;
+            // if (a && b) {
+            //     return b.code.indexOf(a.code) >= 0 ? 1 : 0;
+            // } else {
+            //     return 0;
+            // }
+        });
+        for (const b of this.bases) {
+            b.reg = new RegExp(b.code, 'igm');
+        }
+    }
+
+    _calculateExpr(expr) {
+        let formula = expr;
+        for (const b of this.bases) {
+            formula = formula.replace(b.reg, b.value);
+        }
+        const percent = formula.match(this.percentReg);
+        if (percent) {
+            for (const p of percent) {
+                const v = math.eval(p.replace('%', '/100'));
+                formula = formula.replace(p, v);
+            }
+        }
+        try {
+            const value = math.eval(formula);
+            return value;
+        } catch (err) {
+            return 0;
+        }
+    }
+
+    async calculateExpr(expr) {
+        await this.getCalcBase();
+        return this._calculateExpr(expr);
+    }
+}
+
+module.exports = MaterialCalculate;

+ 24 - 2
app/public/js/material.js

@@ -19,6 +19,16 @@ function loadUpdateMaterials(newMaterial, fields) {
         }
     }
 }
+
+function resetTpTable() {
+    const rate = $('#changeRate').val();
+    const bqhs = ZhCalc.round(ZhCalc.mul(m_tp, 1+rate/100), 2);
+    const jzbqhs = ZhCalc.round(ZhCalc.mul(ZhCalc.add(pre_tp, m_tp), 1+rate/100), 2);
+    $('#tp_set').find('td').eq(1).text(ZhCalc.round(m_tp, 2));
+    $('#tp_set').find('td').eq(2).text(ZhCalc.round(ZhCalc.add(pre_tp, m_tp), 2));
+    $('#rate_set').find('td').eq(1).text(bqhs !== 0 ? bqhs : '');
+    $('#rate_set').find('td').eq(2).text(jzbqhs !== 0 ? jzbqhs : '');
+}
 $(document).ready(() => {
     autoFlashHeight();
     const materialSpread = SpreadJsObj.createNewSpread($('#material-spread')[0]);
@@ -64,7 +74,6 @@ $(document).ready(() => {
     materialSpreadSetting.imageClick = function (data) {
         if (data.t_type === 2) {
             $('#bcyy').modal('show');
-            console.log(data);
             $('#materialbillsId').val(data.id);
             $('#expr').val(data.expr);
             if (!readOnly && data.mid === materialID) {
@@ -152,6 +161,8 @@ $(document).ready(() => {
             const sheet = materialSpread.getActiveSheet();
             const select = SpreadJsObj.getSelectObject(sheet);
             postData(window.location.pathname + '/save', {type: 'del', id: select.id}, function (result) {
+                m_tp = result.m_tp;
+                resetTpTable();
                 const index = materialBillsData.indexOf(select);
                 materialBillsData.splice(index, 1);
                 sheet.deleteRows(index, 1);
@@ -240,6 +251,8 @@ $(document).ready(() => {
                 select.m_tp = materialCol.getValue.m_tp(select);
                 // 更新至服务器
                 postData(window.location.pathname + '/save', { type:'update', updateData: select }, function (result) {
+                    m_tp = result.m_tp;
+                    resetTpTable();
                     SpreadJsObj.reLoadRowData(info.sheet, info.row);
                 }, function () {
                     select[col.field] = orgValue;
@@ -440,10 +453,19 @@ $(document).ready(() => {
             const expr = $('#expr').val();
             // 判断表达式格式
             const [valid, msg] = ExprObj._checkExpr(expr);
-            console.log(msg);
             if (!valid) {
                 toastr.error(msg);
             }
+            postData(window.location.pathname + '/save', { type:'expr', id: $('#materialbillsId').val(), expr: expr }, function (result) {
+                m_tp = result.m_tp;
+                resetTpTable();
+                const sheet = materialSpread.getActiveSheet();
+                const select = SpreadJsObj.getSelectObject(sheet);
+                const index = materialBillsData.indexOf(select);
+                materialBillsData.splice(index, 1, result.info);
+                SpreadJsObj.reLoadRowData(sheet, index);
+                $('#bcyy').modal('hide');
+            });
         })
     } else {
         // SpreadJsObj.forbiddenSpreadContextMenu('#material-spread', materialSpread);

+ 82 - 3
app/service/material_bills.js

@@ -9,6 +9,7 @@
  */
 
 const auditConst = require('../const/audit').material;
+const materialConst = require('../const/material');
 
 module.exports = app => {
     class MaterialBills extends app.BaseService {
@@ -54,8 +55,22 @@ module.exports = app => {
             if (!this.ctx.tender || !this.ctx.material) {
                 throw '数据错误';
             }
-            // 判断是否可删
-            return await this.deleteById(id);
+            // 判断t_type是否为费用,且存在quantity,m_spread值
+            const transaction = await this.db.beginTransaction();
+            try {
+                const mbInfo = await this.getDataById(id);
+                await transaction.delete(this.tableName, { id });
+                let m_tp = this.ctx.material.m_tp;
+                if (mbInfo.t_type === materialConst.t_type[1].value && mbInfo.quantity !== null && mbInfo.m_spread !== null) {
+                    // 金额发生变化,则重新计算本期金额
+                    m_tp = await this.calcMaterialMTp(transaction);
+                }
+                await transaction.commit();
+                return m_tp;
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
         }
 
         /**
@@ -70,9 +85,29 @@ module.exports = app => {
             delete data.in_time;
             delete data.m_tp;
             // 判断是否可修改
-            return await this.db.update(this.tableName, data);
+            // 判断t_type是否为费用
+            const transaction = await this.db.beginTransaction();
+            try {
+                await transaction.update(this.tableName, data);
+                let m_tp = this.ctx.material.m_tp;
+                if (data.t_type === materialConst.t_type[1].value) {
+                    m_tp = await this.calcMaterialMTp(transaction);
+                }
+                await transaction.commit();
+                return m_tp;
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
         }
 
+        /**
+         * 更新新一期的quantity和截止上期金额并返回本期总金额
+         * @param transaction
+         * @param tid
+         * @param mid
+         * @returns {Promise<number>}
+         */
         async updateNewMaterial(transaction, tid, mid) {
             const materialBillsData = await this.getAllDataByCondition({ where: { tid } });
             let m_tp = 0;
@@ -112,6 +147,50 @@ module.exports = app => {
             await transaction.update(this.tableName, updateData);
             return await this.ctx.helper.round(this.ctx.helper.mul(mb.quantity, mb.m_spread), 2);
         }
+
+        /**
+         * 修改 expr和quantity值,返回本期金额和单条数据
+         * @param data
+         * @returns {Promise<void>}
+         */
+        async updateFYQuantity(data) {
+            if (!this.ctx.tender || !this.ctx.material) {
+                throw '数据错误';
+            }
+            const transaction = await this.db.beginTransaction();
+            try {
+                const mbInfo = await this.getDataById(data.id);
+                await transaction.update(this.tableName, data);
+                let m_tp = this.ctx.material.m_tp;
+                if (mbInfo.quantity !== data.quantity) {
+                    m_tp = await this.calcMaterialMTp(transaction);
+                }
+                await transaction.commit();
+                const returnData = {
+                    m_tp,
+                    info: await this.getDataById(data.id),
+                }
+                return returnData;
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+        }
+
+        // 更改计算总金额并返回值
+        async calcMaterialMTp(transaction) {
+            // 金额发生变化,则重新计算本期金额
+            const sql = 'SELECT SUM(`m_spread`*`quantity`) as total_price FROM ' + this.tableName + ' WHERE `tid` = ?';
+            const sqlParam = [this.ctx.tender.id];
+            const tp = await transaction.queryOne(sql, sqlParam);
+            console.log(tp);
+            const updateData2 = {
+                id: this.ctx.material.id,
+                m_tp: tp.total_price,
+            };
+            await transaction.update(this.ctx.service.material.tableName, updateData2);
+            return tp.total_price;
+        }
     }
 
     return MaterialBills;

+ 2 - 2
app/view/material/info.ejs

@@ -48,7 +48,7 @@
                         <div class="col-4 p-0">
                             <table class="table table-sm table-bordered">
                                 <tr><th></th><th>本期金额</th><th>截止本期金额</th></tr>
-                                <tr><td>材料价差费用</td><td><%= material.m_tp %></td><td><%= material.m_tp !== null ? ctx.helper.round(ctx.helper.add(material.pre_tp, material.m_tp), 2) : null %></td></tr>
+                                <tr id="tp_set"><td>材料价差费用</td><td><%= material.m_tp %></td><td><%= material.m_tp !== null ? ctx.helper.round(ctx.helper.add(material.pre_tp, material.m_tp), 2) : null %></td></tr>
                                 <tr id="rate_set"><td>材料价差费用(含税)</td><td><%= material.m_tp !== null ? ctx.helper.mul(material.m_tp, 1+material.rate/100) : null %></td><td><%= material.m_tp !== null ? ctx.helper.round(ctx.helper.mul(ctx.helper.add(material.pre_tp, material.m_tp), 1+material.rate/100), 2) : null %></td></tr>
                             </table>
                         </div>
@@ -73,7 +73,7 @@
     const materialListData = JSON.parse('<%- JSON.stringify(materialListData) %>');
     const readOnly = <%- material.readOnly %>;
     const materialID = <%- material.id %>;
-    const m_tp = <%= material.m_tp !== null ? material.m_tp : 0 %>;
+    let m_tp = <%= material.m_tp !== null ? material.m_tp : 0 %>;
     const pre_tp = <%= material.pre_tp !== null ? material.pre_tp : 0 %>;
     const calcBase = JSON.parse('<%- JSON.stringify(calcBase) %>');
 </script>