Sfoglia il codice sorgente

1. 小数位数,根据台账、第一期审批状态限制修改
2. 小数位数,修改后重算清单
3. 清单精度,根据台账审批状态限制修改
4. 清单精度,修改后重算清单、部位明细

MaiXinRong 5 anni fa
parent
commit
60a701392c

+ 10 - 1
app/controller/tender_controller.js

@@ -314,7 +314,16 @@ module.exports = app => {
                     }
                 }
 
-                await ctx.service.tenderInfo.saveTenderInfo(ctx.tender.id, data);
+                if (data.decimal) {
+                    if (ctx.tender.data.user_id !== ctx.session.sessionUser.accountId) throw '仅原报可修改小数位数';
+                    await ctx.service.tenderInfo.saveDecimal(ctx.tender.id, data.decimal, ctx.tender.info.decimal);
+                } else if (data.precision) {
+                    if (ctx.tender.data.user_id !== ctx.session.sessionUser.accountId) throw '仅原报可修改清单精度';
+                    await ctx.service.tenderInfo.savePrecision(ctx.tender.id,
+                        data.precision, ctx.tender.info.precision, ctx.tender.info.decimal);
+                } else {
+                    await ctx.service.tenderInfo.saveTenderInfo(ctx.tender.id, data);
+                }
                 ctx.body = { err: 0, msg: '', data: JSON.parse(ctx.request.body.data) };
             } catch (err) {
                 this.log(err);

+ 0 - 1
app/extend/helper.js

@@ -589,7 +589,6 @@ module.exports = {
      * @param fields - 有效数据的数组
      */
     filterValidFields(data, fields) {
-
         if (data) {
             const result = {};
             for (const prop in data) {

+ 52 - 10
app/public/js/tender.js

@@ -162,13 +162,13 @@ $(document).ready(function() {
         spread.bind(spreadNS.Events.EditEnded, function (e, info) {
             const value = _.toNumber(info.editingText);
             if (!_.isInteger(value)) {
-                toast('请输入0-6的整数', 'warning');
+                toastr.warning('请输入0-6的整数');
                 sheet.setText(info.row, info.col, '0');
             } else if (value > 6) {
-                toast('请输入0-6的整数', 'warning');
+                toastr.warning('请输入0-6的整数');
                 sheet.setText(info.row, info.col, '6');
             } else if (value < 0) {
-                toast('请输入0-6的整数', 'warning');
+                toastr.warning('请输入0-6的整数');
                 sheet.setText(info.row, info.col, '0');
             }
         });
@@ -208,7 +208,7 @@ $(document).ready(function() {
                 }
             }
             if (bHint) {
-                toast('请输入0-6的整数', 'warning');
+                toastr.warning('请输入0-6的整数');
             }
         });
 
@@ -248,8 +248,21 @@ $(document).ready(function() {
             precision.other.value = _.toNumber(sheet.getText(13, 2));
             return precision;
         }
+        function checkPrecisionMinLimit(precision, limit) {
+            for (const unit of precision) {
+                if (precision[unit].value < limit[unit].value) {
+                    if (precision[unit].unit) {
+                        toastr.warning('台账已审批通过,清单精度不可减少,单位为' + limit[unit].unit + '的清单的精度不可小于' + limit[unit].value);
+                    } else {
+                        toastr.warning('台账已审批通过,清单精度不可减少,其他清单的精度不可小于' + limit[unit].value);
+                    }
+                    return false;
+                }
+            }
+            return true;
+        };
 
-        return {loadPrecisonProperty, setReadOnly, getNewPrecisionData, };
+        return {loadPrecisonProperty, setReadOnly, getNewPrecisionData, checkPrecisionMinLimit};
     })();
     // 合同参数
     const dealObj = (function () {
@@ -290,10 +303,10 @@ $(document).ready(function() {
         spread.bind(spreadNS.Events.EditEnded, function (e, info) {
             const value = _.toNumber(info.editingText);
             if (_.isNaN(value)) {
-                toast('请输入不超过万亿的数字', 'warning');
+                toastr.warning('请输入不超过万亿的数字');
                 info.sheet.setText(info.row, info.col, '0');
             } else if (value > Math.pow(10, 13)) {
-                toast('请输入不超过万亿的数字', 'warning');
+                toastr.warning('请输入不超过万亿的数字');
                 info.sheet.setText(info.row, info.col, '0');
             }
             if (info.row === 1 || info.row === 2) {
@@ -329,7 +342,7 @@ $(document).ready(function() {
                 }
             }
             if (bHint) {
-                toast('请输入不超过万亿的数字', 'warning');
+                toastr.warning('请输入不超过万亿的数字');
             }
             calcHtjMinusZlj();
         });
@@ -549,13 +562,41 @@ $(document).ready(function() {
                 payTp: _.toNumber($('#decimal-pay-tp').val()),
             }
         };
+        if (ledgerChecked) {
+            if (prop.decimal.up < property.decimal.up) {
+                toastr.warning('台账已审批完成,单价的小数位数,不可小于' + property.decimal.up);
+                return;
+            }
+            if (prop.decimal.tp < property.decimal.tp) {
+                toastr.warning('台账已审批完成,金额的小数位数,不可小于' + property.decimal.tp);
+                return;
+            }
+        }
+        if (firstStageChecked) {
+            if (property.decimal.pay) {
+                if (!prop.decimal.pay) {
+                    toastr.warning('第一期已审批完成,不可取消合同支付单独设置');
+                    return;
+                }
+                if (prop.decimal.payTp < property.decimal.payTp) {
+                    toastr.warning('第一期已审批完成,单独设置的合同支付小数位数,不可小于' + property.decimal.payTp);
+                    return;
+                }
+            } else {
+                if (prop.decimal.pay) {
+                    toastr.warning('第一期已审批完成,合同支付不可单独设置');
+                    return;
+                }
+            }
+        }
+        if (ledgerChecked && !precisionObj.checkPrecisionMinLimit(prop.decimal, property.decimal)) return;
         const tenderId = window.location.pathname.split('/')[2];
         postData('/tender/' + tenderId + '/save', prop, function (data) {
             setReadOnly('#v-pills-2', true);
             property.decimal = data.decimal;
             $('#post-2').parent().hide();
             $('#edit-2').parent().show();
-        });
+        }, null, true);
     });
 
     /**
@@ -577,13 +618,14 @@ $(document).ready(function() {
     // 提交
     $('#post-3').click(() => {
         const prop = { precision: precisionObj.getNewPrecisionData() };
+        if (ledgerChecked && !precisionObj.checkPrecisionMinLimit(prop.precision, property.precision)) return;
         const tenderId = window.location.pathname.split('/')[2];
         postData('/tender/' + tenderId + '/save', prop, function (data) {
             precisionObj.setReadOnly(true);
             property.precision = data.precision;
             $('#post-3').parent().hide();
             $('#edit-3').parent().show();
-        });
+        }, null, true);
     });
 
     /**

+ 10 - 0
app/service/ledger.js

@@ -238,6 +238,16 @@ module.exports = app => {
             return await this.db.query(sql, sqlParam);
         }
 
+        async getTenderUsedUnits(tenderId) {
+            const sql = 'SELECT unit ' +
+                '  FROM ' + this.tableName +
+                '  WHERE tender_id = ? and is_leaf = true' +
+                '  GROUP By unit';
+            const sqlParam = [tenderId];
+            const units = this.db.query(sql, sqlParam);
+            return this._.map(units, 'unit');
+        }
+
         /**
          * 统计子节点total_price
          * @param {Number} tenderId - 标段id

+ 11 - 0
app/service/pos.js

@@ -55,6 +55,17 @@ module.exports = app => {
             // return await this.db.query(sql, sqlParam);
         }
 
+        async getPosDataByUnits(tenderId, units) {
+            console.log(units);
+            const sql = 'SELECT p.id, p.lid, p.sgfh_qty, p.sjcl_qty, p.qtcl_qty' +
+                '  FROM ' + this.tableName + ' p' +
+                '  LEFT JOIN ' + this.ctx.service.ledger.tableName + ' b' +
+                '  ON p.lid = b.id ' +
+                '  WHERE p.tid = ? and b.unit IN (?)';
+            const sqlParam = [tenderId, units];
+            return await this.db.query(sql, sqlParam);
+        }
+
         async _insertPosData(transaction, data, tid) {
             data.id = this.uuid.v4();
             data.tid = tid;

+ 111 - 0
app/service/tender_info.js

@@ -82,6 +82,117 @@ module.exports = app => {
             }
             await this.db.update(this.tableName, data, {where: {tid: tenderId}});
         }
+
+        async savePrecision(tenderId, newPrecision, oldPrecision, decimal) {
+            const changePrecision = [];
+            const units = await this.ctx.service.ledger.getTenderUsedUnits(tenderId);
+            const defUnits = this._.map(newPrecision, 'units');
+            const otherUnits = units.filter(function (u) {return defUnits.indexOf(u) === -1});
+            let changeUnits = [];
+            for (const prop in newPrecision) {
+                if (oldPrecision[prop]) {
+                    if (newPrecision[prop].value < oldPrecision[prop].value) {
+                        changePrecision.push(newPrecision[prop]);
+                    }
+                } else {
+                    changePrecision.push(newPrecision[prop]);
+                }
+            }
+            for (const cp of changePrecision) {
+                if (cp.unit) {
+                    changeUnits.push(cp.unit);
+                } else {
+                    changeUnits.push(otherUnits);
+                }
+            }
+            changeUnits = this._.flatten(changeUnits);
+
+            if (changeUnits.length > 0) {
+                const bills = await this.ctx.service.ledger.getAllDataByCondition({
+                    columns: ['id', 'unit', 'unit_price', 'sgfh_qty', 'sjcl_qty', 'qtcl_qty', 'deal_qty'],
+                    where: {tender_id: tenderId, unit: changeUnits, is_leaf: true}
+                });
+                const pos = changeUnits.length > 0 ? await this.ctx.service.pos.getPosDataByUnits(tenderId, changeUnits) : [];
+
+                for (const b of bills) {
+                    const precision = this.ctx.helper.findPrecision(newPrecision, b.unit);
+                    const bPos = this._.filter(pos, {lid: b.id});
+                    if (bPos.length > 0) {
+                        let sgfh_qty = 0, sjcl_qty = 0, qtcl_qty = 0, quantity = 0;
+                        for (const p of bPos) {
+                            this.ctx.helper.checkFieldPrecision(p, ['sgfh_qty', 'sjcl_qty', 'qtcl_qty'], precision.value);
+                            p.quantity = this.ctx.helper.add(this.ctx.helper.add(p.sgfh_qty, p.sjcl_qty), p.qtcl_qty);
+                            sgfh_qty = this.ctx.helper.add(sgfh_qty, p.sgfh_qty);
+                            sjcl_qty = this.ctx.helper.add(sjcl_qty, p.sjcl_qty);
+                            qtcl_qty = this.ctx.helper.add(qtcl_qty, p.qtcl_qty);
+                            quantity = this.ctx.helper.add(quantity, p.quantity);
+                        }
+                        b.sgfh_qty = sgfh_qty;
+                        b.sjcl_qty = sjcl_qty;
+                        b.qtcl_qty = qtcl_qty;
+                        b.quantity = quantity;
+                    } else {
+                        this.ctx.helper.checkFieldPrecision(b, ['sgfh_qty', 'sjcl_qty', 'qtcl_qty', 'deal_qty'], precision.value);
+                    }
+                    b.quantity = this.ctx.helper.add(this.ctx.helper.add(b.sgfh_qty, b.sjcl_qty), b.qtcl_qty);
+                    b.sgfh_tp = this.ctx.helper.mul(b.sgfh_qty, b.unit_price, decimal.tp);
+                    b.sjcl_tp = this.ctx.helper.mul(b.sjcl_qty, b.unit_price, decimal.tp);
+                    b.qtcl_tp = this.ctx.helper.mul(b.qtcl_qty, b.unit_price, decimal.tp);
+                    b.deal_tp = this.ctx.helper.mul(b.deal_qty, b.unit_price, decimal.tp);
+                    b.total_price = this.ctx.helper.mul(b.quantity, b.unit_price, decimal.tp);
+                }
+
+                const transaction = await this.db.beginTransaction();
+                try {
+                    await transaction.update(this.tableName,
+                        {precision: JSON.stringify(newPrecision)}, {where: {tid: tenderId}});
+                    if (bills.length > 0) await transaction.updateRows(this.ctx.service.ledger.tableName, bills);
+                    if (pos.length > 0) await transaction.updateRows(this.ctx.service.pos.tableName, pos);
+                    await transaction.commit();
+                } catch (err) {
+                    await transaction.rollback();
+                    throw err;
+                }
+            } else {
+                await this.db.update(this.tableName,
+                    {precision: JSON.stringify(newPrecision)}, {where: {tid: tenderId}});
+            }
+        }
+
+        async saveDecimal(tenderId, newDecimal, oldDecimal) {
+            const changeBills = [], calcUp = newDecimal.up < oldDecimal.up, calcTp = newDecimal.tp !== oldDecimal.tp;
+            if (calcUp || calcTp) {
+                const bills = await this.ctx.service.ledger.getAllDataByCondition({
+                    columns: ['id', 'unit_price', 'sgfh_qty', 'sjcl_qty', 'qtcl_qty', 'deal_qty', 'quantity'],
+                    where: {tender_id: tenderId, is_leaf: true}
+                });
+                for (const b of bills) {
+                    const cb = { id: b.id };
+                    cb.unit_price = calcUp ? this.ctx.helper.round(b.unit_price, newDecimal.up) : b.unit_price;
+                    cb.sgfh_tp = this.ctx.helper.mul(b.sgfh_qty, cb.unit_price, newDecimal.tp);
+                    cb.sjcl_tp = this.ctx.helper.mul(b.sjcl_qty, cb.unit_price, newDecimal.tp);
+                    cb.qtcl_tp = this.ctx.helper.mul(b.qtcl_qty, cb.unit_price, newDecimal.tp);
+                    cb.deal_tp = this.ctx.helper.mul(b.deal_qty, cb.unit_price, newDecimal.tp);
+                    cb.total_price = this.ctx.helper.mul(b.quantity, cb.unit_price, newDecimal.tp);
+                    changeBills.push(cb);
+                }
+            }
+            if (changeBills.length > 0) {
+                const transaction = await this.db.beginTransaction();
+                try {
+                    await transaction.update(this.tableName,
+                        {decimal: JSON.stringify(newDecimal)}, { where: { tid: tenderId }});
+                    await transaction.updateRows(this.ctx.service.ledger.tableName, changeBills);
+                    await transaction.commit();
+                } catch(error) {
+                    await transaction.rollback();
+                    throw error;
+                }
+            } else {
+                await this.db.update(this.tableName,
+                    {decimal: JSON.stringify(newDecimal)}, { where: { tid: tenderId }});
+            }
+        }
     }
 
     return TenderInfo;

+ 8 - 0
app/view/tender/detail.ejs

@@ -386,6 +386,8 @@
                                     </div>
                                 </div>
                                 <div class="tab-pane fade" id="v-pills-2" role="tabpanel" >
+                                    <% if (((tender.ledger_status === audit.ledger.status.uncheck || tender.ledger_status === audit.ledger.status.checkNo) && tender.user_id === ctx.session.sessionUser.accountId)
+                                            || (lastStage && lastStage.user_id === ctx.session.sessionUser.accountId && (lastStage.status === audit.stage.status.checkNo || lastStage.status === audit.stage.status.uncheck))) { %>
                                     <!--操作-->
                                     <div class="d-flex justify-content-end mt-3">
                                         <span>
@@ -396,6 +398,7 @@
                                             <button type="button" class="btn btn-sm btn-outline-danger" id="cancel-2"><i class="fa fa-close"></i>  取消</button>
                                         </span>
                                     </div>
+                                    <% } %>
                                     <!--小数位数-->
                                     <legend class="mt-3">小数位数</legend>
                                     <div class="form-group">
@@ -441,6 +444,8 @@
                                     </div>
                                 </div>
                                 <div class="tab-pane fade" id="v-pills-3" role="tabpanel" >
+                                    <% if (((tender.ledger_status === audit.ledger.status.uncheck || tender.ledger_status === audit.ledger.status.checkNo) && tender.user_id === ctx.session.sessionUser.accountId)
+                                            || (lastStage && lastStage.user_id === ctx.session.sessionUser.accountId && (lastStage.status === audit.stage.status.checkNo || lastStage.status === audit.stage.status.uncheck))) { %>
                                     <!--操作-->
                                     <div class="d-flex justify-content-end mt-3">
                                         <div class="alert alert-danger m-0 p-1 px-2" id="hint-3" style="display: none"><i class="fa fa-smile-o mr-2"></i>A simple danger alert—check it out!</div>
@@ -452,6 +457,7 @@
                                             <button type="button" class="btn btn-sm btn-outline-danger" id="cancel-3"><i class="fa fa-close"></i> 取消</button>
                                         </div>
                                     </div>
+                                    <% } %>
                                     <legend class="mt-3">清单精度</legend>
                                     <!--默认显示-->
                                     <div class="form-group" id="precision-spread" style="height: 365px; width: 600px;">
@@ -757,4 +763,6 @@
 </script>
 <script>
     let property = JSON.parse('<%- JSON.stringify(tenderInfo) %>');
+    let ledgerChecked = <%- tender.ldeger_status === audit.ledger.status.checked %>;
+    let firstStageChecked = <%- !lastStage || (lastStage.order === 1 && lastStage.status !== audit.stage.status.checked) %>
 </script>