Browse Source

费用类型

MaiXinRong 2 năm trước cách đây
mục cha
commit
14afb6e6ef

+ 4 - 0
app/const/spread.js

@@ -44,6 +44,7 @@ const withCl = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@'},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '费用类别', colSpan: '1', rowSpan: '2', field: 'node_type', hAlign: 0, width: 100, cellType: 'customizeCombo'},
             {title: 'ex_memo2', colSpan: '1', rowSpan: '2', field: 'ex_memo2', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
             {title: 'ex_memo3', colSpan: '1', rowSpan: '2', field: 'ex_memo3', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
         ],
@@ -94,6 +95,7 @@ const withoutCl = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'sgfh_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@'},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '费用类别', colSpan: '1', rowSpan: '2', field: 'node_type', hAlign: 0, width: 100, cellType: 'customizeCombo'},
             {title: 'ex_memo2', colSpan: '1', rowSpan: '2', field: 'ex_memo2', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
             {title: 'ex_memo3', colSpan: '1', rowSpan: '2', field: 'ex_memo3', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
         ],
@@ -147,6 +149,7 @@ const withClGcl = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@'},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '费用类别', colSpan: '1', rowSpan: '2', field: 'node_type', hAlign: 0, width: 100, cellType: 'customizeCombo'},
             {title: 'ex_memo2', colSpan: '1', rowSpan: '2', field: 'ex_memo2', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
             {title: 'ex_memo3', colSpan: '1', rowSpan: '2', field: 'ex_memo3', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
         ],
@@ -176,6 +179,7 @@ const withoutClGcl = {
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'sgfh_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@'},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '费用类别', colSpan: '1', rowSpan: '2', field: 'node_type', hAlign: 0, width: 100, cellType: 'customizeCombo'},
             {title: 'ex_memo2', colSpan: '1', rowSpan: '2', field: 'ex_memo2', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
             {title: 'ex_memo3', colSpan: '1', rowSpan: '2', field: 'ex_memo3', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
         ],

+ 14 - 0
app/const/standard.js

@@ -16,9 +16,13 @@ const nodeType = [
     {text: '土地拆迁补偿', value: 4},
     {text: '预备费', value: 5},
     {text: '暂列金额', value: 6},
+    {text: '尾工工程', value: 18},
     {text: '计日工', value: 7},
+    {text: '材料调差', value: 15},
     {text: '价差调整', value: 8},
     {text: '索赔', value: 9},
+    {text: '零星工程', value: 16},
+    {text: '报废工程', value: 17},
     {text: '新增费用', value: 10},
     {text: '其他费用', value: 11},
     {text: '回收金额', value: 12},
@@ -32,10 +36,20 @@ const jrg = nodeType.find(x => {
 const zlj = nodeType.find(x => {
     return x.text === '暂列金额';
 });
+const jafTypeName = ['', '计日工', '材料调差', '价差调整', '索赔', '零星工程', '保费工程'];
+const jafType = nodeType.filter(x => {
+    return jafTypeName.indexOf(x.text) >= 0;
+});
+const zljTypeName = ['', '暂列金额', '尾工工程'];
+const zljType = nodeType.filter(x => {
+    return zljTypeName.indexOf(x.text) >= 0;
+});
 
 
 module.exports = {
     nodeType,
+    jafType,
+    zljType,
     jrg,
     zlj,
 };

+ 2 - 0
app/controller/ledger_audit_controller.js

@@ -11,6 +11,7 @@ const auditConst = require('../const/audit').ledger;
 const shenpiConst = require('../const/shenpi');
 const measureType = require('../const/tender').measureType;
 const spreadSetting = require('../lib/spread_setting');
+const stdConst = require('../const/standard');
 
 module.exports = app => {
     class LedgerAuditController extends app.BaseController {
@@ -75,6 +76,7 @@ module.exports = app => {
                 renderData.posSpreadSetting = JSON.stringify(posSpread);
                 renderData.readOnly = true;
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.ledger.audit);
+                renderData.nodeType = stdConst.nodeType;
                 await this.layout('ledger/audit.ejs', renderData, 'ledger/audit_modal.ejs');
             } catch (err) {
                 this.log(err);

+ 1 - 0
app/controller/ledger_controller.js

@@ -153,6 +153,7 @@ module.exports = app => {
                     shenpiConst,
                     categoryData,
                     syncLedgerUrl: syncLedger ? `${ctx.app.config.url3f}/${syncLedger.pull_class}/sync-tz/${tender.id}` : '',
+                    nodeType: stdConst.nodeType,
                 };
                 if ((tender.data.ledger_status === auditConst.status.uncheck || tender.data.ledger_status === auditConst.status.checkNo) && tender.data.user_id === ctx.session.sessionUser.accountId) {
                     // renderData.accountGroup = accountGroup;

+ 2 - 0
app/controller/revise_controller.js

@@ -286,6 +286,7 @@ module.exports = app => {
                 user,
                 auditHistory,
                 shenpiConst,
+                nodeType: stdConst.nodeType,
             };
         }
 
@@ -483,6 +484,7 @@ module.exports = app => {
                     auditConst: audit.revise,
                     user,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.revise.history),
+                    nodeType: stdConst.nodeType,
                 };
                 await this.layout('revise/history.ejs', renderData, 'revise/history_modal.ejs');
             } catch (err) {

+ 7 - 6
app/public/js/ledger.js

@@ -78,11 +78,6 @@ $(document).ready(function() {
         markExpandSubKey: window.location.pathname.split('/')[2],
         calcFields: ['deal_tp', 'sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'],
     };
-    // if (checkTzMeasureType()) {
-    //     treeSetting.calcFields = ['sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'];
-    // } else {
-    //     treeSetting.calcFields = ['deal_tp', 'sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'];
-    // }
     treeSetting.calcFun = function (node) {
         node.dgn_price = ZhCalc.round(ZhCalc.div(node.total_price, node.dgn_qty1), 2);
     };
@@ -953,6 +948,7 @@ $(document).ready(function() {
         },
         editStarting(e, info) {
             if (!info.sheet.zh_setting || !info.sheet.zh_tree) return;
+            const tree = info.sheet.zh_tree;
             const col = info.sheet.zh_setting.cols[info.col];
             const node = info.sheet.zh_tree.nodes[info.row];
             if (!node) {
@@ -985,6 +981,11 @@ $(document).ready(function() {
                 case 'dgn_qty2':
                     info.cancel = !_.isEmpty(node.b_code);
                     break;
+                case 'node_type':
+                    const parent = tree.getParent(node);
+                    const topParent = tree.getTopParent(node);
+                    info.cancel = !parent || !topParent || [1, 5].indexOf(topParent.node_type) < 0;
+                    break;
             }
         },
         sortCode: function (sheet) {
@@ -1072,6 +1073,7 @@ $(document).ready(function() {
     //     {title: 'full_path', colSpan: '1', rowSpan: '2', field: 'full_path', hAlign: 2, width: 60, type: 'Number', readOnly: true},
     //     {title: 'node_type', colSpan: '1', rowSpan: '2', field: 'node_type', hAlign: 2, width: 60, type: 'Number', readOnly: true}
     // );
+    sjsSettingObj.setNodeTypeCol(ledgerSpreadSetting.cols, [{field: 'node_type'}]);
     SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), ledgerSpreadSetting);
     SpreadJsObj.selChangedRefreshBackColor(ledgerSpread.getActiveSheet());
     // 绑定事件
@@ -2229,7 +2231,6 @@ $(document).ready(function() {
 
     postData(window.location.pathname + '/load', {}, function (data) {
         ledgerTree.loadDatas(data.bills);
-        console.log(data.bills.find(x => { return x.b_code === '102-4'}));
         treeCalc.calculateAll(ledgerTree);
         for (const t of data.tags) {
             t.node = ledgerTree.datas.find(x => {return x.id === t.lid});

+ 1 - 0
app/public/js/ledger_audit.js

@@ -45,6 +45,7 @@ $(document).ready(() => {
     const ledgerTree = createNewPathTree('fx', treeSetting);
     sjsSettingObj.setFxTreeStyle(ledgerSpreadSetting, sjsSettingObj.FxTreeStyle.jz);
     if (thousandth) sjsSettingObj.setTpThousandthFormat(ledgerSpreadSetting);
+    sjsSettingObj.setNodeTypeCol(ledgerSpreadSetting.cols, [{field: 'node_type'}]);
     SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), ledgerSpreadSetting);
 
     // 初始化 部位明细

+ 7 - 0
app/public/js/path_tree.js

@@ -409,8 +409,15 @@ const createNewPathTree = function (type, setting) {
         getParent(node) {
             return this.getItems(node[this.setting.pid]);
         };
+        getTopParent(node) {
+            const parents = this.getAllParents(node);
+            parents.sort((a, b) => { return a.level - b.level; });
+            return parents[0];
+        };
         getAllParents(node) {
             const parents = [];
+            if (!node) return parents;
+
             if (node.full_path && node.full_path !== '') {
                 const parentIds = node.full_path.split('-');
                 for (const id of parentIds) {

+ 1 - 0
app/public/js/revise.js

@@ -88,6 +88,7 @@ $(document).ready(() => {
             },
         },
     ];
+    sjsSettingObj.setNodeTypeCol(billsSpreadSetting.cols, [{field: 'node_type'}]);
     SpreadJsObj.initSheet(billsSheet, billsSpreadSetting);
     const posSpread = SpreadJsObj.createNewSpread($('#pos-spread')[0]);
     const posSheet = posSpread.getActiveSheet();

+ 1 - 0
app/public/js/revise_history.js

@@ -16,6 +16,7 @@ $(document).ready(() => {
     const billsSheet = billsSpread.getActiveSheet();
     sjsSettingObj.setFxTreeStyle(billsSpreadSetting, sjsSettingObj.FxTreeStyle.jz);
     if (thousandth) sjsSettingObj.setTpThousandthFormat(billsSpreadSetting);
+    sjsSettingObj.setNodeTypeCol(billsSpreadSetting.cols, [{field: 'node_type'}]);
     SpreadJsObj.initSheet(billsSheet, billsSpreadSetting);
     const posSpread = SpreadJsObj.createNewSpread($('#pos-spread')[0]);
     const posSheet = posSpread.getActiveSheet();

+ 22 - 1
app/public/js/shares/sjs_setting.js

@@ -100,9 +100,30 @@ const sjsSettingObj = (function () {
             }
         }
     };
+    const setNodeTypeCol = function (cols, rela) {
+        for (const r of rela) {
+            const col = _.find(cols, {field: r.field});
+            if (col) {
+                col.comboItems = nodeType;
+                col.cellType = 'specCombo';
+                col.comboEdit = function (sheet, data) {
+                    if (!data) return false;
+
+                    const tree = sheet.zh_tree;
+                    if (!tree) return false;
+
+                    const parent = tree.getParent(data);
+                    if (!parent) return false;
+
+                    const topParent = tree.getTopParent(data);
+                    return [1, 5].indexOf(topParent.node_type) >= 0;
+                };
+            }
+        }
+    };
     return {
         setFxTreeStyle, FxTreeStyle, setGridSelectStyle,
         setTpThousandthFormat, setThousandthFormat, setTpColsThousandthFormat,
-        setPropValue, set3FCols, setQcCols, setOrgPriceCol,
+        setPropValue, set3FCols, setQcCols, setOrgPriceCol, setNodeTypeCol,
     };
 })();

+ 50 - 0
app/public/js/spreadjs_rela/spreadjs_zh.js

@@ -697,6 +697,13 @@ const SpreadJsObj = {
             }
             sheet.getRange(-1, col, -1, 1).cellType(sheet.extendCellType.stageCombo);
         }
+        if (colSetting.cellType === 'specCombo') {
+            if (!sheet.extendCellType.specCombo) {
+                sheet.extendCellType.specCombo = this.CellType.getSpecComboCellType(colSetting.comboItems);
+                SpreadJsObj._addActivePaintEvents(sheet, sheet.extendCellType.specCombo);
+            }
+            sheet.getRange(-1, col, -1, 1).cellType(sheet.extendCellType.specCombo);
+        }
         if (colSetting.cellType === 'datepicker') {
             if (!sheet.extendCellType.datepicker) {
                 sheet.extendCellType.datepicker = this.CellType.getDatePickerCellType();
@@ -2329,6 +2336,49 @@ const SpreadJsObj = {
             combo.itemHeight(10).editorValueType(spreadNS.CellTypes.EditorValueType.value).items(items);
             return combo;
         },
+        getSpecComboCellType: function (items) {
+            const ComboCellType = function () {};
+            ComboCellType.prototype = new spreadNS.CellTypes.ComboBox();
+            const proto = ComboCellType.prototype;
+            proto.paintValue = function (ctx, value, x, y, w, h, style, options) {
+                const sheet = options.sheet;
+                const setting = options.sheet.zh_setting;
+                const col = setting.cols[options.col];
+                const data = SpreadJsObj.getSelectObject(options.sheet);
+                const comboEdit = (col.comboEdit && Object.prototype.toString.apply(col.comboEdit) === "[object Function]")
+                    ? col.comboEdit(options.sheet, data)
+                    : (col.comboEdit !== undefined ? col.comboEdit : true);
+                if (options.row === sheet.getActiveRowIndex() && options.col === sheet.getActiveColumnIndex()
+                    && !sheet.getCell(options.row, options.col).locked() && comboEdit) {
+                    spreadNS.CellTypes.ComboBox.prototype.paintValue.apply(this, arguments);
+                } else {
+                    spreadNS.CellTypes.Base.prototype.paintValue.apply(this, arguments);
+                }
+            };
+            proto.processMouseEnter = function (hitinfo) {
+                hitinfo.sheet.repaint(hitinfo.cellRect);
+            };
+            proto.getHitInfo = function (x, y, cellStyle, cellRect, options) {
+                const sheet = options.sheet;
+                if (options.row === sheet.getActiveRowIndex() && options.col === sheet.getActiveColumnIndex()
+                    && !sheet.getCell(options.row, options.col).locked()) {
+                    return spreadNS.CellTypes.ComboBox.prototype.getHitInfo.apply(this, [x, y, cellStyle, cellRect, options]);
+                } else {
+                    return  {
+                        x: x,
+                        y: y,
+                        row: options.row,
+                        col: options.col,
+                        cellStyle: cellStyle,
+                        cellRect: cellRect,
+                        sheetArea: options.sheetArea
+                    };
+                }
+            };
+            const combo = new ComboCellType();
+            combo.itemHeight(10).items(items).editorValueType(spreadNS.CellTypes.EditorValueType.value);
+            return combo;
+        },
         getStageComboCellType: function () {
             const ComboCellType = function () {};
             ComboCellType.prototype = new spreadNS.CellTypes.ComboBox();

+ 1 - 0
app/view/ledger/audit.ejs

@@ -118,4 +118,5 @@
             $('.modal-title').text('重新上报')
         }
     });
+    const nodeType = JSON.parse('<%- JSON.stringify(nodeType) %>');
 </script>

+ 1 - 1
app/view/ledger/explode.ejs

@@ -354,11 +354,11 @@
         }
     });
     const syncLedgerUrl = '<%- syncLedgerUrl %>';
+    const nodeType = JSON.parse('<%- JSON.stringify(nodeType) %>');
 </script>
 <% if ((tender.ledger_status === auditConst.status.uncheck || tender.ledger_status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === tender.user_id) { %>
 <script>
     const accountList = JSON.parse('<%- JSON.stringify(accountList) %>');
     const accountGroup = JSON.parse('<%- JSON.stringify(accountGroup) %>');
-
 </script>
 <% } %>

+ 1 - 0
app/view/revise/history.ejs

@@ -101,4 +101,5 @@
     const isTz = <%- ctx.tender.data.measure_type === measureType.tz.value %>;
     const billsSpreadSetting = JSON.parse('<%- JSON.stringify(ledgerSpread) %>');
     const thousandth = <%- ctx.tender.info.display.thousandth %>;
+    const nodeType = JSON.parse('<%- JSON.stringify(nodeType) %>');
 </script>

+ 1 - 0
app/view/revise/info.ejs

@@ -251,4 +251,5 @@
             $('.modal-title').text('重新上报')
         }
     });
+    const nodeType = JSON.parse('<%- JSON.stringify(nodeType) %>');
 </script>