Browse Source

变更差值对比

laiguoran 3 years ago
parent
commit
e42a011944

+ 13 - 0
app/controller/change_controller.js

@@ -594,6 +594,17 @@ module.exports = app => {
                 // 根据auditStatus获取审批人列表
                 // 根据auditStatus获取审批人列表
                 const auditList = await ctx.service.changeAudit.getListByStatus(change, auditStatus);
                 const auditList = await ctx.service.changeAudit.getListByStatus(change, auditStatus);
 
 
+                // 获取变更方案的清单
+                let planList = [];
+                let showPlanBtn = false;
+                if (ctx.session.sessionProject.page_show.openChangePlan) {
+                    const planInfo = change.plan_code ? await ctx.service.changePlan.getDataByCondition({ tid: ctx.tender.id, code: change.plan_code }) : null;
+                    showPlanBtn = change.plan_code !== null && change.plan_code !== '';
+                    if (planInfo && planInfo.id) {
+                        planList = await ctx.service.changePlanList.getAllDataByCondition({ where: { cpid: planInfo.id } });
+                    }
+                }
+
                 // 获取用户人验证手机号
                 // 获取用户人验证手机号
                 const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
                 const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
                 const auth_mobile = pa.auth_mobile;
                 const auth_mobile = pa.auth_mobile;
@@ -608,6 +619,8 @@ module.exports = app => {
                     attList,
                     attList,
                     whiteList,
                     whiteList,
                     auditList,
                     auditList,
+                    showPlanBtn,
+                    planList,
                     tpUnit: change.tp_decimal ? change.tp_decimal : ctx.tender.info.decimal.tp,
                     tpUnit: change.tp_decimal ? change.tp_decimal : ctx.tender.info.decimal.tp,
                     upUnit: change.up_decimal ? change.up_decimal : ctx.tender.info.decimal.up,
                     upUnit: change.up_decimal ? change.up_decimal : ctx.tender.info.decimal.up,
                     authMobile: auth_mobile,
                     authMobile: auth_mobile,

+ 170 - 0
app/public/js/change_information.js

@@ -14,6 +14,59 @@ const is_numeric = (value) => {
         return !Number.isNaN(Number(value)) && value.toString().trim() !== '';
         return !Number.isNaN(Number(value)) && value.toString().trim() !== '';
     }
     }
 };
 };
+function sortByCode(a, b) {
+    let code1 = a.code.split('-');
+    let code2 = b.code.split('-');
+    let code1length = code1.length;
+    let code2length = code2.length;
+    for (let i = 0; i < code1length; i ++) {
+        if (i+1 <= code2length) {
+            if (code1[i] != code2[i]) {
+                if (/^\d+$/.test(code1[i]) && /^\d+$/.test(code2[i])) {
+                    return parseInt(code1[i]) - parseInt(code2[i]);
+                } else if (!/^\d+$/.test(code1[i]) && /^\d+$/.test(code2[i])) {
+                    return 1;
+                } else if (/^\d+$/.test(code1[i]) && !/^\d+$/.test(code2[i])) {
+                    return -1;
+                } else {
+                    const str1length = code1[i].length;
+                    const str2length = code2[i].length;
+                    for (let j = 0; j < str1length; j++) {
+                        if (j+1 <= str2length) {
+                            if (code1[i].charAt(j) != code2[i].charAt(j)) {
+                                return code1[i].charAt(j).charCodeAt() - code2[i].charAt(j).charCodeAt();
+                            }  else if (j+1 == str1length && code1[i].charAt(j) == code2[i].charAt(j)) {
+                                if (str1length == str2length) {
+                                    return 0;
+                                } else {
+                                    return str1length - str2length;
+                                }
+                            }
+                        } else {
+                            if (j+1 >= str1length) {
+                                return 1;
+                            } else {
+                                return -1;
+                            }
+                        }
+                    }
+                }
+            } else if (i+1 == code1length && code1[i] == code2[i]) {
+                if (code1length == code2length) {
+                    return 0;
+                } else {
+                    return code1length - code2length;
+                }
+            }
+        } else {
+            if (i+1 >= code1length) {
+                return 1;
+            } else {
+                return -1;
+            }
+        }
+    }
+}
 $(document).ready(() => {
 $(document).ready(() => {
     //初始化所有附件列表
     //初始化所有附件列表
     getAllList();
     getAllList();
@@ -236,6 +289,123 @@ $(document).ready(() => {
         }
         }
     });
     });
 
 
+    // 差值对比信息获取
+    let czSpread = null;
+    const czSpreadSetting = {
+        cols: [
+            {title: '清单编号', colSpan: '1', rowSpan: '2', field: 'code', hAlign: 0, width: 80},
+            {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 120},
+            {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 60},
+            {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 60, type: 'Number', getValue: 'getValue.unit_price'},
+            {title: '变更方案|数量', colSpan: '2|1', rowSpan: '1|1', field: 'pamount', hAlign: 2, width: 60, type: 'Number', getValue: 'getValue.pamount'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'pa_tp', hAlign: 2, width: 80, type: 'Number', getValue: 'getValue.pa_tp'},
+            {title: '变更令|数量', colSpan: '2|1', rowSpan: '1|1', field: 'camount', hAlign: 2, width: 60, type: 'Number', getValue: 'getValue.camount'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'ca_tp', hAlign: 2, width: 80, type: 'Number', getValue: 'getValue.ca_tp'},
+            {title: '差值对比|数量', colSpan: '2|1', rowSpan: '1|1', field: 'czamount', hAlign: 2, width: 60, type: 'Number', getValue: 'getValue.czamount'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'cz_tp', hAlign: 2, width: 80, type: 'Number', getValue: 'getValue.cz_tp'},
+        ],
+        emptyRows: 0,
+        headRows: 2,
+        headRowHeight: [25, 25],
+        defaultRowHeight: 21,
+        headerFont: '12px 微软雅黑',
+        font: '12px 微软雅黑',
+        readOnly: true,
+        localCache: {
+            key: 'changes-cz',
+            colWidth: true,
+        }
+    };
+    const czCol = {
+        getValue: {
+            unit_price: function(data) {
+                return ZhCalc.round(data.unit_price, unitPriceUnit);
+            },
+            pa_tp: function (data) {
+                return ZhCalc.round(ZhCalc.mul(ZhCalc.round(data.unit_price, unitPriceUnit), ZhCalc.round(data.pamount, findDecimal(data.unit))), totalPriceUnit);
+            },
+            ca_tp: function (data) {
+                return ZhCalc.round(ZhCalc.mul(ZhCalc.round(data.unit_price, unitPriceUnit), ZhCalc.round(data.camount, findDecimal(data.unit))), totalPriceUnit);
+            },
+            pamount: function (data) {
+                return ZhCalc.round(data.pamount, findDecimal(data.unit));
+            },
+            camount: function (data) {
+                return ZhCalc.round(data.camount, findDecimal(data.unit));
+            },
+            czamount: function (data) {
+                return ZhCalc.sub(ZhCalc.round(data.camount, findDecimal(data.unit)), ZhCalc.round(data.pamount, findDecimal(data.unit)));
+            },
+            cz_tp: function (data) {
+                return ZhCalc.round(ZhCalc.mul(ZhCalc.round(data.unit_price, unitPriceUnit), ZhCalc.round(ZhCalc.sub(ZhCalc.round(data.camount, findDecimal(data.unit)), ZhCalc.round(data.pamount, findDecimal(data.unit))), findDecimal(data.unit))), totalPriceUnit);
+            },
+        }
+    };
+    const czSpreadObj = {
+        makeSjsFooter: function () {
+            // 增加汇总行并设为锁定禁止编辑状态
+            czSpread.getActiveSheet().addRows(czSpread.getActiveSheet().getRowCount(), 1);
+            czSpread.getActiveSheet().setValue(czSpread.getActiveSheet().getRowCount() - 1, 0, '合计');
+            czSpread.getActiveSheet().setStyle(czSpread.getActiveSheet().getRowCount() - 1, -1, style1);
+            czSpreadObj.countSum();
+        },
+        countSum: function () {
+            const rowCount = czSpread.getActiveSheet().getRowCount();
+            let pSum = 0,
+                cSum = 0,
+                czSum = 0;
+            for (var i = 0; i < rowCount - 1; i++) {
+                pSum = ZhCalc.add(pSum, czSpread.getActiveSheet().getValue(i, 5));
+                cSum = ZhCalc.add(cSum, czSpread.getActiveSheet().getValue(i, 7));
+                czSum = ZhCalc.add(czSum, czSpread.getActiveSheet().getValue(i, 9));
+            }
+            czSpread.getActiveSheet().setValue(czSpread.getActiveSheet().getRowCount() - 1, 5, pSum !== 0 ? pSum : null);
+            czSpread.getActiveSheet().setValue(czSpread.getActiveSheet().getRowCount() - 1, 7, cSum !== 0 ? cSum : null);
+            czSpread.getActiveSheet().setValue(czSpread.getActiveSheet().getRowCount() - 1, 9, czSum !== 0 ? czSum : null);
+        },
+    };
+
+    $('#bgfadb').on('shown.bs.modal', function () {
+        if (!czSpread) {
+            czSpread = SpreadJsObj.createNewSpread($('#cz-spread')[0]);
+            SpreadJsObj.initSpreadSettingEvents(czSpreadSetting, czCol);
+            SpreadJsObj.initSheet(czSpread.getActiveSheet(), czSpreadSetting);
+        }
+        const cList = [];
+        const newChangeList = _.cloneDeep(changeList);
+        for (const cl of newChangeList) {
+            const cIndex = _.findIndex(cList, { code: cl.code, name: cl.name, unit: cl.unit, unit_price: cl.unit_price});
+            if (cIndex !== -1) {
+                cList[cIndex].spamount = ZhCalc.add(cList[cIndex].spamount, cl.spamount);
+            } else {
+                cList.push(cl);
+            }
+        }
+        // 生成差值对比数据列表
+        const czList = [];
+        const newPlanList = _.cloneDeep(planList);
+        for (const c of cList) {
+            const planInfo = _.find(newPlanList, { code: c.code, name: c.name, unit: c.unit, unit_price: c.unit_price });
+            const pamount = planInfo ? planInfo.spamount : null;
+            if (planInfo) {
+                _.remove(newPlanList, (item) => item === planInfo);
+            }
+            czList.push({ code: c.code, name: c.name, unit: c.unit, unit_price: c.unit_price, camount: c.spamount, pamount });
+        }
+        if (newPlanList.length > 0) {
+            for (const np of newPlanList) {
+                czList.push({ code: np.code, name: np.name, unit: np.unit, unit_price: np.unit_price, camount: null, pamount: np.spamount });
+            }
+        }
+        if (czList.length > 0) {
+            // 按清单编号排序
+            czList.sort(sortByCode);
+        }
+        // sjs设置
+        SpreadJsObj.loadSheetData(czSpread.getActiveSheet(), SpreadJsObj.DataType.Data, czList);
+        czSpreadObj.makeSjsFooter();
+    });
+
     $.subMenu({
     $.subMenu({
         menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
         menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
         toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
         toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',

+ 17 - 0
app/view/change/information.ejs

@@ -54,6 +54,11 @@
                         </div>
                         </div>
                     </div>
                     </div>
                 <% } %>
                 <% } %>
+                <% if (showPlanBtn) { %>
+                <div class="d-inline-block ml-3">
+                    <a class="btn btn-sm btn-primary" href="#bgfadb" data-toggle="modal" data-target="#bgfadb">差值对比</a>
+                </div>
+                <% } %>
             </div>
             </div>
             <div class="ml-auto" id="sp-btn">
             <div class="ml-auto" id="sp-btn">
                 <!--info状态区分-->
                 <!--info状态区分-->
@@ -440,6 +445,18 @@
     console.log(changeList);
     console.log(changeList);
     const style1 = new GC.Spread.Sheets.Style();
     const style1 = new GC.Spread.Sheets.Style();
     style1.locked = true;
     style1.locked = true;
+    const changePlanList = JSON.parse(unescape('<%- escape(JSON.stringify(planList)) %>'));
+    const planList = [];
+    if (changePlanList.length > 0) {
+        for (const cp of changePlanList) {
+            const planIndex = _.findIndex(planList, { code: cp.code, name: cp.name, unit: cp.unit, unit_price: cp.unit_price});
+            if (planIndex !== -1) {
+                planList[planIndex].spamount = ZhCalc.add(planList[planIndex].spamount, cp.spamount);
+            } else {
+                planList.push(cp);
+            }
+        }
+    }
 </script>
 </script>
 <% if (auditStatus === 1 || auditStatus === 2 || auditStatus === 9) { %>
 <% if (auditStatus === 1 || auditStatus === 2 || auditStatus === 9) { %>
 <script>
 <script>

+ 17 - 1
app/view/change/information_modal.ejs

@@ -1138,7 +1138,23 @@
         </div>
         </div>
     </div>
     </div>
 </div>
 </div>
-
+<% if (showPlanBtn) { %>
+<div class="modal fade" id="bgfadb" data-backdrop="static">
+    <div class="modal-dialog modal-lg" style="max-width:900px;" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">清单差值对比</h5>
+            </div>
+            <div class="modal-body">
+                <div class="modal-height-300" id="cz-spread"></div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
+            </div>
+        </div>
+    </div>
+</div>
+<% } %>
 <script type="text/javascript">
 <script type="text/javascript">
     const csrf = '<%= ctx.csrf %>';
     const csrf = '<%= ctx.csrf %>';
     const authMobile = '<%= authMobile %>';
     const authMobile = '<%= authMobile %>';